From 8f6fabba4b17ecf3fda12bef12a879fa459b8cef Mon Sep 17 00:00:00 2001 From: ozhozh Date: Wed, 2 Sep 2009 20:26:34 +0000 Subject: [PATCH] 1.4-alpha massive commit: - now using a global object $ydb for everything related to DB and other globally needed stuff - change in DB schema: now storing URLs with their keyword as used in shorturl, allowing for any keyword length - change in DB schema: new table for storing various options including next_id, dropping table of the same name - change in DB schema: new table for storing hits (for stats) - added an upgrader from 1.3 to 1.4 - improved the installer, with .htaccess file creation git-svn-id: http://yourls.googlecode.com/svn/trunk@103 12232710-3e20-11de-b438-597f59cd7555 --- admin/index.php | 38 ++- admin/index_ajax.php | 6 +- admin/upgrade.php | 94 +++++++ changelog.txt | 32 +++ includes/class-mysql.php | 7 - includes/config-sample.php | 17 +- includes/functions-install.php | 38 ++- includes/functions-upgrade.php | 159 +++++++++++ includes/functions-xml.php | 2 +- includes/functions.php | 489 ++++++++++++++++++++++++++++----- includes/load-yourls.php | 24 ++ includes/version.php | 4 +- js/insert.js | 19 +- yourls-go.php | 24 +- 14 files changed, 805 insertions(+), 148 deletions(-) create mode 100644 admin/upgrade.php create mode 100644 changelog.txt create mode 100644 includes/functions-upgrade.php create mode 100644 includes/load-yourls.php diff --git a/admin/index.php b/admin/index.php index 87a1cb7..bc2a3e7 100644 --- a/admin/index.php +++ b/admin/index.php @@ -10,8 +10,8 @@ $where = $search_display = $search_text = $search_url = $url = $keyword = ''; $search_in_text = 'URL'; $search_in_sql = 'url'; -$sort_by_text = 'ID'; -$sort_by_sql = 'id'; +$sort_by_text = 'Short URL'; +$sort_by_sql = 'keyword'; $sort_order_text = 'Descending Order'; $sort_order_sql = 'desc'; $page = ( isset( $_GET['page'] ) ? intval($_GET['page']) : 1 ); @@ -30,9 +30,9 @@ // Searching if(!empty($search) && !empty($_GET['s_in'])) { switch($_GET['s_in']) { - case 'id': - $search_in_text = 'ID'; - $search_in_sql = 'id'; + case 'keyword': + $search_in_text = 'Short URL'; + $search_in_sql = 'keyword'; break; case 'url': $search_in_text = 'URL'; @@ -53,9 +53,9 @@ // Sorting if(!empty($_GET['s_by']) || !empty($_GET['s_order'])) { switch($_GET['s_by']) { - case 'id': - $sort_by_text = 'ID'; - $sort_by_sql = 'id'; + case 'keyword': + $sort_by_text = 'Short URL'; + $sort_by_sql = 'keyword'; break; case 'url': $sort_by_text = 'URL'; @@ -87,8 +87,8 @@ } // Get URLs Count for current filter, total links in DB & total clicks -$total_items = $ydb->get_var("SELECT COUNT(id) FROM $table_url WHERE 1=1 $where"); -$totals = $ydb->get_row("SELECT COUNT(id) as c, SUM(clicks) as s FROM $table_url WHERE 1=1"); +$total_items = $ydb->get_var("SELECT COUNT(keyword) FROM $table_url WHERE 1=1 $where"); +$totals = $ydb->get_row("SELECT COUNT(keyword) as c, SUM(clicks) as s FROM $table_url WHERE 1=1"); // This is a bookmarklet if ( isset( $_GET['u'] ) ) { @@ -96,10 +96,10 @@ $url = $_GET['u']; $keyword = ( isset( $_GET['k'] ) ? $_GET['k'] : '' ); - $return = yourls_add_new_link( $url, $keyword, $ydb ); + $return = yourls_add_new_link( $url, $keyword ); // If fails because keyword already exist, retry with no keyword - if ( $return['status'] == 'fail' && $return['code'] == 'error:keyword' ) { + if ( isset( $return['status'] ) && $return['status'] == 'fail' && isset( $return['code'] ) && $return['code'] == 'error:keyword' ) { $msg = $return['message']; $return = yourls_add_new_link( $url, '', $ydb ); $return['message'] .= ' ('.$msg.')'; @@ -175,9 +175,8 @@ - - + @@ -207,20 +206,19 @@ get_results("SELECT * FROM $table_url WHERE 1=1 $where ORDER BY $sort_by_sql $sort_order_sql LIMIT $offset, $perpage;"); - if($url_results) { + $url_results = $ydb->get_results("SELECT * FROM `$table_url` WHERE 1=1 $where ORDER BY $sort_by_sql $sort_order_sql LIMIT $offset, $perpage;"); + if( $url_results ) { foreach( $url_results as $url_result ) { - $base36 = yourls_int2string($url_result->id); + $keyword = yourls_sanitize_string($url_result->keyword); $timestamp = strtotime($url_result->timestamp); - $id = ($url_result->id); $url = stripslashes($url_result->url); $ip = $url_result->ip; $clicks = $url_result->clicks; - echo yourls_table_add_row($id, $base36, $url, $ip, $clicks, $timestamp ); + echo yourls_table_add_row( $keyword, $url, $ip, $clicks, $timestamp ); } } else { - echo ''; + echo ''; } ?> diff --git a/admin/index_ajax.php b/admin/index_ajax.php index 583b024..cf34acb 100644 --- a/admin/index_ajax.php +++ b/admin/index_ajax.php @@ -16,17 +16,17 @@ break; case 'edit_display': - $row = yourls_table_edit_row ( $_REQUEST['id'] ); + $row = yourls_table_edit_row ( $_REQUEST['keyword'] ); echo yourls_json_encode( array('html' => $row) ); break; case 'edit_save': - $return = yourls_edit_link( $_REQUEST['url'], $_REQUEST['id'], $_REQUEST['newid'] ); + $return = yourls_edit_link( $_REQUEST['url'], $_REQUEST['keyword'], $_REQUEST['newkeyword'] ); echo yourls_json_encode($return); break; case 'delete': - $query = yourls_delete_link_by_id( $_REQUEST['id'] ); + $query = yourls_delete_link_by_keyword( $_REQUEST['keyword'] ); echo yourls_json_encode(array('success'=>$query)); break; diff --git a/admin/upgrade.php b/admin/upgrade.php new file mode 100644 index 0000000..1d076e0 --- /dev/null +++ b/admin/upgrade.php @@ -0,0 +1,94 @@ + +

+ YOURLS: Your Own URL Shortener
+ YOURLS
+

+ +

Your are logged in as: . Logout

+ + +
+ +

Upgrade YOURLS

+ +Upgrade not required. Go back to play!

'; + + +} else { + /* + step 1: create new tables and populate them, update old tables structure, + step 2: convert each row of outdated tables if needed + step 3: if applicable finish updating outdated tables (indexes etc) + step 4: update version & db_version in options, this is all done! + */ + + // From what are we upgrading? + if ( isset( $_GET['oldver'] ) && isset( $_GET['oldsql'] ) ) { + $oldver = intval( $_GET['oldver'] ); + $oldsql = intval( $_GET['oldsql'] ); + } else { + list( $oldver, $oldsql ) = yourls_get_current_version_from_sql(); + } + + // To what are we upgrading ? + $newver = YOURLS_VERSION; + $newsql = YOURLS_DB_VERSION; + + // Let's go + $step = ( isset( $_GET['step'] ) ? intval( $_GET['step'] ) : 0 ); + switch( $step ) { + + default: + case 0: + echo " +

Your current installation needs to be upgraded.

+

Please, pretty please, it is recommended that + you backup your database (you should do this regularly anyway)

+

Nothing awful *should* happen, but this doesn't mean it *won't* happen, right?

+

Once you are ready, press Upgrade!

+
+ + + + + + + "; + + break; + + case 1: + case 2: + case 3: + yourls_upgrade( $step, $oldver, $newver, $oldsql, $newsql ); + break; + + case 4: + yourls_upgrade( 4, $oldver, $newver, $oldsql, $newsql ); + $admin = YOURLS_SITE.'/admin/index.php'; + echo " +

Your installation is now up to date :)

+

Go back to the admin interface

+ "; + } + +} + + +?> +
+ + diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..f1c909b --- /dev/null +++ b/changelog.txt @@ -0,0 +1,32 @@ +*** YOURLS Changelog *** + +This file attempts to list the major changes through all versions of YOURLS. For a much more detailed +list, simply refer to the commit messages: http://code.google.com/p/yourls/source/list + +1.0 +- initial release + +1.0.1 +- don't remember. Trivial stuff probably. + +1.1 +- don't remember. Some little bugs I guess. + +1.2 +- don't remember. A few tiny stuff for sure. + +1.3-RC1 +- added bookmarklet and tools page +- improved XSS filter when adding new URL +- code cleanup in admin/index.php to separate code and display +- added favicon +- stricter coding to prevent notices with undefined indexes +- hide PHP notices & SQL errors & warnings, unless YOURLS_DEBUG constant set to true + +1.4 +- now using a global object $ydb for everything related to DB and other globally needed stuff +- change in DB schema: now storing URLs with their keyword as used in shorturl, allowing for any keyword length +- change in DB schema: new table for storing various options including next_id, dropping table of the same name +- change in DB schema: new table for storing hits (for stats) +- added an upgrader from 1.3 to 1.4 +- improved the installer, with .htaccess file creation diff --git a/includes/class-mysql.php b/includes/class-mysql.php index e5fade8..ef7ed9a 100644 --- a/includes/class-mysql.php +++ b/includes/class-mysql.php @@ -394,11 +394,4 @@ function mysql_version() { return mysql_get_server_info( $this->dbh ) ; } } - -// Create the YOURLS DB object -if ( function_exists( 'yourls_db_connect' ) ) { - global $ydb; - yourls_db_connect(); -} - ?> \ No newline at end of file diff --git a/includes/config-sample.php b/includes/config-sample.php index 7c7ac8e..544d773 100644 --- a/includes/config-sample.php +++ b/includes/config-sample.php @@ -15,17 +15,23 @@ /** MySQL hostname */ define('YOURLS_DB_HOST', 'localhost'); -/** MySQL URL table name. Don't change this if in doubt. */ +/** MySQL table name to store URLs. Don't change this if in doubt. */ define('YOURLS_DB_TABLE_URL', 'yourls_url'); /** MySQL Next ID table name. Don't change this if in doubt. */ define('YOURLS_DB_TABLE_NEXTDEC', 'yourls_next_id'); +/** MySQL table name to store a few options. Don't change this if in doubt. */ +define('YOURLS_DB_TABLE_OPTIONS', 'yourls_options'); + +/** MySQL table name to log redirects (for stats). Don't change this if in doubt. */ +define('YOURLS_DB_TABLE_LOG', 'yourls_log'); + /* ** Site options */ -/** Turn this on to enable error reporting. Recommended value is false **/ +/** Turn this on to enable error reporting. Leave this to false **/ define('YOURLS_DEBUG', false); /** Short domain URL, no trailing slash */ @@ -70,9 +76,4 @@ /******************** DO NOT EDIT ANYTHING ELSE ********************/ - -// Include everything except auth functions -require_once (dirname(__FILE__).'/version.php'); -require_once (dirname(__FILE__).'/functions.php'); -require_once (dirname(__FILE__).'/functions-baseconvert.php'); -require_once (dirname(__FILE__).'/class-mysql.php'); +require_once (dirname(__FILE__).'/load-yourls.php'); diff --git a/includes/functions-install.php b/includes/functions-install.php index bbeee76..6f040e7 100644 --- a/includes/functions-install.php +++ b/includes/functions-install.php @@ -142,23 +142,42 @@ function yourls_create_sql_tables() { $create_tables = array(); $create_tables[YOURLS_DB_TABLE_URL] = 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_URL.'` ('. - '`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,'. + '`keyword` varchar(200) NOT NULL,'. '`url` VARCHAR(200) NOT NULL,'. '`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,'. '`ip` VARCHAR(41) NOT NULL,'. '`clicks` INT(10) UNSIGNED NOT NULL,'. - 'PRIMARY KEY (`id`)'. - ') ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;'; + 'PRIMARY KEY (`keyword`)'. + ') ENGINE=MyISAM DEFAULT CHARSET=utf8 ;'; + + $create_tables[YOURLS_DB_TABLE_OPTIONS] = + 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_OPTIONS.'` ('. + '`option_id` bigint(20) unsigned NOT NULL auto_increment,'. + '`option_name` varchar(64) NOT NULL default "",'. + '`option_value` longtext NOT NULL,'. + 'PRIMARY KEY (`option_id`,`option_name`),'. + 'KEY `option_name` (`option_name`)'. + ') ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;'; + + $create_tables[YOURLS_DB_TABLE_LOG] = + 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_LOG.'` ('. + '`click_id` int(11) NOT NULL auto_increment,'. + '`click_time` datetime NOT NULL,'. + '`shorturl` varchar(200) NOT NULL,'. + '`referrer` varchar(200) NOT NULL,'. + '`user_agent` varchar(255) NOT NULL,'. + '`ip_address` varchar(41) NOT NULL,'. + '`country_code` char(2) NOT NULL,'. + 'PRIMARY KEY (`click_id`),'. + 'KEY `shorturl` (`shorturl`,`referrer`,`country_code`)'. + ') ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;'; - $create_tables[YOURLS_DB_TABLE_NEXTDEC] = - 'CREATE TABLE `'.YOURLS_DB_TABLE_NEXTDEC.'` ('. - '`next_id` BIGINT NOT NULL ,'. - 'PRIMARY KEY (`next_id`)'. - ') ENGINE = MYISAM ;'; // Insert Initial Records $insert_queries = array(); - $insert_queries[] = 'INSERT INTO '.YOURLS_DB_TABLE_NEXTDEC.' VALUES (1)'; + $insert_queries[] = 'INSERT INTO '.YOURLS_DB_TABLE_OPTIONS.' VALUES (1, "next_id", 1)'; + $insert_queries[] = 'INSERT INTO '.YOURLS_DB_TABLE_OPTIONS.' VALUES (2, "version", '.YOURLS_VERSION.')'; + $insert_queries[] = 'INSERT INTO '.YOURLS_DB_TABLE_OPTIONS.' VALUES (3, "db_version", '.YOURLS_DB_VERSION.')'; $create_table_count = 0; $insert_query_count = 0; @@ -197,5 +216,4 @@ function yourls_create_sql_tables() { return array( 'success' => $success_msg, 'error' => $error_msg ); } - ?> diff --git a/includes/functions-upgrade.php b/includes/functions-upgrade.php new file mode 100644 index 0000000..49faf2a --- /dev/null +++ b/includes/functions-upgrade.php @@ -0,0 +1,159 @@ +get_var("SELECT `next_id` FROM `$table`"); + yourls_update_option( 'next_id', $next_id ); + @$ydb->query( "DROP TABLE `$table`" ); +} + +// Create new tables for YOURLS 1.4: options & log +function yourls_create_tables_for_14() { + global $ydb; + + $queries = array(); + + $queries[YOURLS_DB_TABLE_OPTIONS] = + 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_OPTIONS.'` ('. + '`option_id` int(11) unsigned NOT NULL auto_increment,'. + '`option_name` varchar(64) NOT NULL default "",'. + '`option_value` longtext NOT NULL,'. + 'PRIMARY KEY (`option_id`,`option_name`),'. + 'KEY `option_name` (`option_name`)'. + ');'; + + $queries[YOURLS_DB_TABLE_LOG] = + 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_LOG.'` ('. + '`click_id` int(11) NOT NULL auto_increment,'. + '`click_time` datetime NOT NULL,'. + '`shorturl` varchar(200) NOT NULL,'. + '`referrer` varchar(200) NOT NULL,'. + '`user_agent` varchar(255) NOT NULL,'. + '`ip_address` varchar(41) NOT NULL,'. + '`country_code` char(2) NOT NULL,'. + 'PRIMARY KEY (`click_id`),'. + 'KEY `shorturl` (`shorturl`,`referrer`,`country_code`)'. + ');'; + + foreach( $queries as $query ) { + $ydb->query( $query ); + } + + echo "

New tables created. Please wait...

"; + +} + +// Alter table structure, part 1 (change schema, drop index) +function yourls_alter_url_table_to_14() { + global $ydb; + $table = YOURLS_DB_TABLE_URL; + + $alters = array(); + $results = array(); + $alters[] = "ALTER TABLE `$table` CHANGE `id` `keyword` VARCHAR( 200 ) NOT NULL"; + $alters[] = "ALTER TABLE `$table` DROP PRIMARY KEY"; + + foreach ( $alters as $query ) { + $ydb->query( $query ); + } + + echo "

Structure of existing tables updated. Please wait...

"; +} + +// Alter table structure, part 2 (recreate index after the table is up to date) +function yourls_alter_url_table_to_14_part_two() { + global $ydb; + $table = YOURLS_DB_TABLE_URL; + + $alters = array(); + $alters[] = "ALTER TABLE `$table` ADD PRIMARY KEY ( `keyword` )"; + + foreach ( $alters as $query ) { + $ydb->query( $query ); + } + + echo "

New table index created

"; +} + +// Convert each link from 1.3 (id) to 1.4 (keyword) structure +function yourls_update_table_to_14() { + global $ydb; + $table = YOURLS_DB_TABLE_URL; + + // Modify each link to reflect new structure + $chunk = 30; + $from = isset($_GET['from']) ? intval( $_GET['from'] ) : 0 ; + $total = yourls_get_db_stats(); + $total = $total['total_links']; + + $sql = "SELECT `keyword`,`url` FROM `$table` WHERE 1=1 ORDER BY `url` ASC LIMIT $from, $chunk ;"; + + $rows = $ydb->get_results($sql); + + $count = 0; + foreach( $rows as $row ) { + $keyword = $row->keyword; + $url = $row->url; + $newkeyword = yourls_int2string( $keyword ); + $result = $ydb->query("UPDATE `$table` SET `keyword` = '$newkeyword' WHERE `url` = '$url';"); + $count++; + } + + if ( $count == $chunk ) { + // there are probably other rows to convert + $from = $from + $chunk; + $remain = $total - $from; + echo "

Converted $chunk database rows ($remain remaining). Continuing... Please do not close this window until it's finished!

"; + yourls_redirect_javascript( YOURLS_SITE."/admin/upgrade.php?step=2&oldver=1.3&newver=1.4&oldsql=100&newsql=200&from=$from" ); + } else { + // All done + echo '

All rows converted! Please wait...

'; + yourls_redirect_javascript( YOURLS_SITE."/admin/upgrade.php?step=3&oldver=1.3&newver=1.4&oldsql=100&newsql=200" ); + } + +} + diff --git a/includes/functions-xml.php b/includes/functions-xml.php index e0a8829..b1ea51a 100644 --- a/includes/functions-xml.php +++ b/includes/functions-xml.php @@ -30,7 +30,7 @@ function array_transform($array){ $this->text.=""; } } - return $array_text; + //return $array_text; } /*Transform an XML string to associative array "XML Parser Functions"*/ diff --git a/includes/functions.php b/includes/functions.php index 297ee98..92fb79a 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -25,11 +25,11 @@ function yourls_string2int( $str ) { return yourls_base2base(trim($str), YOURLS_URL_CONVERT, 10); } -// Make sure a link id (site.com/1fv) is valid. +// Make sure a link keyword (ie "1fv" as in "site.com/1fv") is valid. function yourls_sanitize_string($in) { if (YOURLS_URL_CONVERT <= 37) $in = strtolower($in); - return substr(preg_replace('/[^a-zA-Z0-9]/', '', $in), 0, 12); + return substr(preg_replace('/[^a-zA-Z0-9]/', '', $in), 0, 199); } // A few sanity checks on the URL @@ -40,8 +40,10 @@ function yourls_sanitize_url($url) { // make sure there's a protocol, add http:// if not if ( !preg_match('!^([a-zA-Z]+://)!', $url ) ) $url = 'http://'.$url; - - return yourls_clean_url($url); + + $url = yourls_clean_url($url); + + return substr( $url, 0, 199 ); } // Function to filter all invalid characters from a URL. Stolen from WP's clean_url() @@ -72,7 +74,8 @@ function yourls_deep_replace($search, $subject){ } -// Make sure an id link is a valid integer (PHP's intval() limits to too small numbers) +// 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) ); } @@ -84,12 +87,16 @@ 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 integer id is reserved (ie reserved URL or an existing page) +// Check to see if a given keyword is reserved (ie reserved URL or an existing page) // Returns bool -function yourls_is_reserved_id($id) { +function yourls_keyword_is_reserved( $keyword ) { global $yourls_reserved_URL; - $keyword = yourls_int2string( yourls_intval($id) ); + if ( in_array( $keyword, $yourls_reserved_URL) or file_exists(dirname(dirname(__FILE__))."/pages/$keyword.php") or is_dir(dirname(dirname(__FILE__))."$keyword") @@ -99,7 +106,7 @@ function yourls_is_reserved_id($id) { return false; } -// Function: Get IP Address +// 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']; @@ -114,37 +121,45 @@ function yourls_get_IP() { $ip_address = explode(',', $ip_address); $ip_address = $ip_address[0]; } + + $ip_address = preg_replace( '/[^0-9a-fA-F:., ]/', '', $ip_address ); + return $ip_address; } // Add the "Edit" row -function yourls_table_edit_row($id) { +function yourls_table_edit_row( $keyword ) { global $ydb; - $id = yourls_intval($id); $table = YOURLS_DB_TABLE_URL; - $url = $ydb->get_row("SELECT `url` FROM `$table` WHERE `id` = '$id';"); - $safe_url = stripslashes($url->url); - $keyword = yourls_int2string($id); - if($url) { - $return = << + $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 = << RETURN; } else { - $return = ''; + $return = ''; } return $return; } // Add a link row -function yourls_table_add_row( $id, $keyword, $url, $ip, $clicks, $timestamp ) { +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); $www = YOURLS_SITE; + $shorturl = YOURLS_SITE.'/'.$keyword; return << + ROW; } @@ -160,32 +175,34 @@ function yourls_get_next_decimal() { function yourls_update_next_decimal($int = '') { global $ydb; - $int = ( $int == '' ) ? 'next+1' : (int)$int ; + $int = ( $int == '' ) ? 'next_id+1' : (int)$int ; $table = YOURLS_DB_TABLE_NEXTDEC; return $ydb->query("UPDATE `$table` set next_id=$int"); } // Delete a link in the DB -function yourls_delete_link_by_id($id) { +function yourls_delete_link_by_keyword( $keyword ) { global $ydb; $table = YOURLS_DB_TABLE_URL; - $id = yourls_intval($id); - return $ydb->query("DELETE FROM `$table` WHERE `id` = $id;"); + $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, $id) { +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(); - return $ydb->query("INSERT INTO `$table` VALUES($id, '$url', '$timestamp', '$ip', 0);"); + $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 = '') { +function yourls_add_new_link( $url, $keyword = '' ) { global $ydb; if ( !$url || $url == 'http://' || $url == 'https://' ) { @@ -196,9 +213,9 @@ function yourls_add_new_link($url, $keyword = '') { } $table = YOURLS_DB_TABLE_URL; - $url = mysql_real_escape_string(yourls_sanitize_url($url)); + $url = mysql_real_escape_string( yourls_sanitize_url($url) ); $strip_url = stripslashes($url); - $url_exists = $ydb->get_row("SELECT id,url FROM `$table` WHERE `url` = '".$strip_url."';"); + $url_exists = $ydb->get_row("SELECT keyword,url FROM `$table` WHERE `url` = '".$strip_url."';"); $ip = yourls_get_IP(); $return = array(); @@ -206,55 +223,55 @@ function yourls_add_new_link($url, $keyword = '') { if( !$url_exists ) { // Custom keyword provided - if ($keyword) { + if ( $keyword ) { $keyword = mysql_real_escape_string(yourls_sanitize_string($keyword)); - if (!yourls_keyword_is_free($keyword, $ydb)) { - // This id either reserved or taken already + if ( !yourls_keyword_is_free($keyword) ) { + // This shorturl either reserved or taken already $return['status'] = 'fail'; $return['code'] = 'error:keyword'; - $return['message'] = 'URL id '.$keyword.' already exists in database or is reserved'; + $return['message'] = 'Short URL '.$keyword.' already exists in database or is reserved'; } else { // all clear, store ! - $id = yourls_string2int($keyword); - yourls_insert_link_in_db($url, $id, $ydb); - $return['url'] = array('id' => $id, 'keyword' => $keyword, 'url' => $strip_url, 'date' => date('Y-m-d H:i:s'), 'ip' => yourls_get_IP() ); + 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( $id, $keyword, $url, yourls_get_IP(), 0, time() ); + $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($ydb); + $id = yourls_get_next_decimal(); + $ok = false; do { - $add_url = @yourls_insert_link_in_db($url, $id, $ydb); - $free = !yourls_is_reserved_id( $id ); + $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_id( $id, $ydb ); - $return['extra_info'] .= '(deleted '.$id.')'; + $delete = yourls_delete_link_by_keyword( $keyword ); + $return['extra_info'] .= '(deleted '.$keyword.')'; } else { // everything ok, populate needed vars - $keyword = yourls_int2string($id); - $return['url'] = array('id' => $id, 'keyword' => $keyword, 'url' => $strip_url, 'date' => $timestamp, 'ip' => $ip); + $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( $id, $keyword, $url, $ip, 0, time() ); + $return['html'] = yourls_table_add_row( $keyword, $url, $ip, 0, time() ); $return['shorturl'] = YOURLS_SITE .'/'. $keyword; } $id++; } while (!$ok); - @yourls_update_next_decimal($id, $ydb); + @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 .'/'. yourls_int2string( $url_exists->id ); + $return['shorturl'] = YOURLS_SITE .'/'. $url_exists->keyword; } return $return; @@ -262,45 +279,42 @@ function yourls_add_new_link($url, $keyword = '') { // Edit a link -function yourls_edit_link($url, $id, $keyword='') { +function yourls_edit_link($url, $keyword, $newkeyword='') { global $ydb; $table = YOURLS_DB_TABLE_URL; $url = mysql_real_escape_string(yourls_sanitize_url($url)); - $id = yourls_intval($id); + $keyword = yourls_sanitize_string( $keyword ); + $newkeyword = yourls_sanitize_string( $newkeyword ); $strip_url = stripslashes($url); - $old_url = $ydb->get_var("SELECT `url` FROM `$table` WHERE `id` = '".$id."';"); - + $old_url = $ydb->get_var("SELECT `url` FROM `$table` WHERE `keyword` = '$keyword';"); // Check if new URL is not here already if ($old_url != $url) { - $url_exists = intval($ydb->get_var("SELECT id FROM `$table` WHERE `url` = '".$strip_url."';")); + $new_url_already_there = intval($ydb->get_var("SELECT COUNT(keyword) FROM `$table` WHERE `url` = '$strip_url';")); } else { - $url_exists = false; + $new_url_already_there = false; } // Check if the new keyword is not here already - $newid = ( $keyword ? yourls_string2int($keyword) : $id ); - if ($newid != $id) { - $id_exists = intval($ydb->get_var("SELECT id FROM `$table` WHERE `id` = '".$newid."';")); - $id_free = yourls_keyword_is_free($keyword, $ydb); - $id_is_ok = ($id_exists == 0) && $id_free; + if ( $newkeyword != $keyword ) { + $keyword_is_ok = yourls_keyword_is_free( $newkeyword ); } else { - $id_is_ok = true; + $keyword_is_ok = true; } // All clear, update - if($url_exists == 0 && $id_is_ok ) { + if ( !$new_url_already_there && $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', `timestamp` = '$timestamp4db', `id` = '$newid' WHERE `id` = $id;"); - if($update_url) { - $return['url'] = array('id' => $newid, 'keyword' => $keyword, 'shorturl' => YOURLS_SITE.'/'.$keyword, 'url' => $strip_url, 'date' => $timestamp4screen); + $update_url = $ydb->query("UPDATE `$table` SET `url` = '$url', `timestamp` = '$timestamp4db', `keyword` = '$newkeyword' WHERE `keyword` = '$keyword';"); + if( $update_url ) { + $return['url'] = array( 'keyword' => $newkeyword, 'shorturl' => YOURLS_SITE.'/'.$newkeyword, 'url' => $strip_url, 'date' => $timestamp4screen); $return['status'] = 'success'; $return['message'] = 'Link updated in database'; } else { $return['status'] = 'fail'; - $return['message'] = 'Error updating '.$strip_url.' (ID: '.$id.') to database'; + $return['message'] = 'Error updating '.$strip_url.' (Short URL: '.$keyword.') to database'; } // Nope @@ -314,15 +328,14 @@ function yourls_edit_link($url, $id, $keyword='') { // Check if keyword id is free (ie not already taken, and not reserved) -function yourls_keyword_is_free($str) { +function yourls_keyword_is_free( $keyword ) { global $ydb; $table = YOURLS_DB_TABLE_URL; - $id = yourls_string2int($str); - if ( yourls_is_reserved_id($id) ) + if ( yourls_keyword_is_reserved($keyword) ) return false; - $already_exists = intval($ydb->get_var("SELECT `id` FROM `$table` WHERE `id` = '".$id."';")); + $already_exists = $ydb->get_var("SELECT COUNT(`keyword`) FROM `$table` WHERE `keyword` = '$keyword';"); if ( $already_exists ) return false; @@ -331,7 +344,7 @@ function yourls_keyword_is_free($str) { // Display a page -function yourls_page($page) { +function yourls_page( $page ) { $include = dirname(dirname(__FILE__))."/pages/$page.php"; if (!file_exists($include)) { die("Page '$page' not found"); @@ -355,6 +368,9 @@ function yourls_db_connect() { if ( $ydb->last_error ) die( $ydb->last_error ); + if ( defined('YOURLS_DEBUG') && YOURLS_DEBUG === true ) + $ydb->show_errors = true; + // return $ydb; } @@ -375,6 +391,29 @@ function yourls_xml_encode($array) { return $converter->array2xml($array); } +// Return long URL associated with keyword. Optional $notfound = string default message if nothing found +function yourls_get_longurl( $keyword, $notfound = false ) { + global $ydb; + $keyword = yourls_sanitize_string( $keyword ); + $table = YOURLS_DB_TABLE_URL; + $url = stripslashes($ydb->get_var("SELECT `url` FROM `$table` WHERE `keyword` = '$keyword'")); + + if( $url ) + return $url; + + return $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 for API stat requests function yourls_api_stats( $filter, $limit ) { global $ydb; @@ -409,7 +448,7 @@ function yourls_api_stats( $filter, $limit ) { foreach ($results as $res) { $return['links']['link_'.$i++] = array( - 'shorturl' => YOURLS_SITE .'/'. yourls_int2string($res->id), + 'shorturl' => YOURLS_SITE .'/'. $res->keyword, 'url' => $res->url, 'timestamp' => $res->timestamp, 'ip' => $res->ip, @@ -417,12 +456,21 @@ function yourls_api_stats( $filter, $limit ) { ); } - $totals = $ydb->get_row("SELECT COUNT(id) as c, SUM(clicks) as s FROM $table_url WHERE 1=1"); - $return['stats'] = array( 'total_links' => $totals->c, 'total_clicks' => $totals->s ); + $return['stats'] = yourls_get_db_stats(); return $return; } + +// 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 ) { switch ( $mode ) { @@ -464,6 +512,7 @@ function yourls_html_head( $context = 'index' ) { case 'login': case 'new': case 'tools': + case 'upgrade': $share = false; $insert = false; $tablesorter = false; @@ -612,7 +661,7 @@ function yourls_html_tfooter( $params = array() ) { function yourls_share_box( $longurl, $shorturl, $title='', $text='' ) { $text = ( $text ? '"'.$text.'" ' : '' ); $title = ( $title ? "$title " : '' ); - $share = $title.$text.$shorturl ; + $share = htmlentities( $title.$text.$shorturl ); $_share = rawurlencode( $share ); $_url = rawurlencode( $shorturl ); $count = 140 - strlen( $share ); @@ -689,4 +738,296 @@ function yourls_http_build_query($data, $prefix=null, $sep=null, $key='', $urlen return implode($sep, $ret); } -// \ No newline at end of file +// 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'] ) { + $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); + + if ( php_sapi_name() != 'cgi-fcgi' ) + header ("$protocol $code $desc"); // This causes problems on IIS and some FastCGI setups + header("Location: $location"); + die(); + } +} + +// Redirect to another page using Javascript +function yourls_redirect_javascript( $location ) { + echo << + //window.location="$location"; + + (if you are not redirected after 10 seconds, please click here) +REDIR; +} + +// Return a HTTP status code +function yourls_get_HTTP_status( $code ) { + $code = intval( $code ); + $headers_desc = array( + 100 => 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', + + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', + 226 => 'IM Used', + + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 306 => 'Reserved', + 307 => 'Temporary Redirect', + + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 422 => 'Unprocessable Entity', + 423 => 'Locked', + 424 => 'Failed Dependency', + 426 => 'Upgrade Required', + + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 506 => 'Variant Also Negotiates', + 507 => 'Insufficient Storage', + 510 => 'Not Extended' + ); + + if ( isset( $headers_desc[$code] ) ) + return $headers_desc[$code]; + else + return ''; +} + + +// Log a redirect (for stats) +function yourls_log_redirect( $keyword ) { + global $ydb; + $table = YOURLS_DB_TABLE_LOG; + + $keyword = yourls_sanitize_string( $keyword ); + $referrer = ( isset( $_SERVER['HTTP_REFERER'] ) ? yourls_sanitize_url( $_SERVER['HTTP_REFERER'] ) : 'direct' ); + $ua = yourls_get_user_agent(); + $ip = yourls_get_IP(); + $location = yourls_get_location( $ip ); + + return $ydb->query( "INSERT INTO `$table` VALUES ('', NOW(), '$url', '$referrer', '$ua', '$ip', '$location')" ); +} + +// Converts an IP to a 2 letter country code, using GeoIP database if available in includes/geo/ +function yourls_get_location( $ip = '', $default = '' ) { + if ( !file_exists( dirname(__FILE__).'/geo/GeoIP.dat') || !file_exists( dirname(__FILE__).'/geo/geoip.inc') ) + return $default; + + if ( $ip = '' ) + $ip = yourls_get_IP(); + + require_once( dirname(__FILE__).'/geo/geoip.inc') ; + $gi = geoip_open( dirname(__FILE__).'/geo/GeoIP.dat', GEOIP_STANDARD); + $location = geoip_country_code_by_addr($gi, $ip); + geoip_close($gi); + + return $location; +} + +// Check if an upgrade is needed +function yourls_upgrade_is_needed() { + // check YOURLS_VERSION && YOURLS_DB_VERSION exist && match values stored in YOURLS_DB_TABLE_OPTIONS + list( $currentver, $currentsql ) = yourls_get_current_version_from_sql(); + + // Using floatval() to get 1.4 from 1.4-alpha + if( ( $currentver < floatval( YOURLS_VERSION ) ) || ( $currentsql < floatval( YOURLS_DB_VERSION ) ) ) + return true; + + return false; +} + +// Get current version & db version as stored in the options DB +function yourls_get_current_version_from_sql() { + if( !defined('YOURLS_DB_TABLE_OPTIONS') ) + die('

Your config.php does not contain all the required constant definitions. Please check config-sample.php and update your config accordingly, there are new stuffs!

'); + + global $ydb; + $table = YOURLS_DB_TABLE_OPTIONS; + $currentver = @$ydb->get_var("SELECT `option_value` FROM $table WHERE `option_name` = 'version'"); + $currentsql = @$ydb->get_var("SELECT `option_value` FROM $table WHERE `option_name` = 'db_version'"); + if( !$currentver ) + $currentver = '1.3'; + if( !$currentsql ) + $currentsql = '100'; + + return array( $currentver, $currentsql); +} + +// Read an option from DB (or from cache if available). Return value or $default if not found +function yourls_get_option( $option_name, $default = false ) { + if ( !isset( $ydb->option[$option_name] ) ) { + global $ydb; + $table = YOURLS_DB_TABLE_OPTIONS; + $option_name = yourls_escape( $option_name ); + $row = $ydb->get_row( "SELECT `option_value` FROM `$table` WHERE `option_name` = '$option_name' LIMIT 1" ); + if ( is_object( $row) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values + $value = $row->option_value; + } else { // option does not exist, so we must cache its non-existence + $value = $default; + } + $ydb->option[$option_name] = yourls_maybe_unserialize( $value ); + } + + return $ydb->option[$option_name]; +} + +// Update (add if doesn't exist) an option to DB +function yourls_update_option( $option_name, $newvalue ) { + global $ydb; + $table = YOURLS_DB_TABLE_OPTIONS; + + $safe_option_name = yourls_escape( $option_name ); + $newvalue = yourls_escape( $newvalue ); + + $oldvalue = yourls_get_option( $safe_option_name ); + + // If the new and old values are the same, no need to update. + if ( $newvalue === $oldvalue ) + return false; + + if ( false === $oldvalue ) { + yourls_add_option( $option_name, $newvalue ); + return true; + } + + $_newvalue = yourls_maybe_serialize( $newvalue ); + + $ydb->query( "UPDATE `$table` SET `option_value` = '$_newvalue' WHERE `option_name` = '$option_name'"); + + if ( $ydb->rows_affected == 1 ) { + $ydb->option[$option_name] = $newvalue; + return true; + } + return false; +} + +// Add an option to the DB +function yourls_add_option( $name, $value = '' ) { + global $ydb; + $table = YOURLS_DB_TABLE_OPTIONS; + $safe_name = yourls_escape( $name ); + $value = yourls_escape( $value ); + + // Make sure the option doesn't already exist. We can check the 'notoptions' cache before we ask for a db query + if ( false !== yourls_get_option( $safe_name ) ) + return; + + $_value = yourls_maybe_serialize( $value ); + + $ydb->query( "INSERT INTO `$table` (`option_name`, `option_value`) VALUES ('$name', '$_value')" ); + $ydb->option[$name] = $value; + return; +} + + +// Delete an option from the DB +function yourls_delete_option( $name ) { + global $ydb; + $table = YOURLS_DB_TABLE_OPTIONS; + $name = yourls_escape( $name ); + + // Get the ID, if no ID then return + $option = $ydb->get_row( "SELECT option_id FROM `$table` WHERE `option_name` = '$name'" ); + if ( is_null($option) || !$option->option_id ) + return false; + $ydb->query( "DELETE FROM `$table` WHERE `option_name` = '$name'" ); + return true; +} + + + +// Serialize data if needed. Stolen from WordPress +function yourls_maybe_serialize( $data ) { + if ( is_array( $data ) || is_object( $data ) ) + return serialize( $data ); + + if ( yourls_is_serialized( $data ) ) + return serialize( $data ); + + return $data; +} + +// Check value to find if it was serialized. Stolen from WordPress +function yourls_is_serialized( $data ) { + // if it isn't a string, it isn't serialized + if ( !is_string( $data ) ) + return false; + $data = trim( $data ); + if ( 'N;' == $data ) + return true; + if ( !preg_match( '/^([adObis]):/', $data, $badions ) ) + return false; + switch ( $badions[1] ) { + case 'a' : + case 'O' : + case 's' : + if ( preg_match( "/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data ) ) + return true; + break; + case 'b' : + case 'i' : + case 'd' : + if ( preg_match( "/^{$badions[1]}:[0-9.E-]+;\$/", $data ) ) + return true; + break; + } + return false; +} + +// Unserialize value only if it was serialized. Stolen from WP +function yourls_maybe_unserialize( $original ) { + if ( yourls_is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in + return @unserialize( $original ); + return $original; +} \ No newline at end of file diff --git a/includes/load-yourls.php b/includes/load-yourls.php new file mode 100644 index 0000000..8de2a46 --- /dev/null +++ b/includes/load-yourls.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/js/insert.js b/js/insert.js index b39e7d4..c2139d9 100644 --- a/js/insert.js +++ b/js/insert.js @@ -5,8 +5,8 @@ $(document).ready(function(){ $('#new_url_form').attr('action', 'javascript:add();'); if ($("#tblUrl tr.nourl_found").length != 1) { $("#tblUrl").tablesorter({ - sortList:[[3,1]], // Sort on column #3 (numbering starts at 0) - headers: { 6: {sorter: false} }, // no sorter on column #6 + sortList:[[2,1]], // Sort on column #3 (numbering starts at 0) + headers: { 5: {sorter: false} }, // no sorter on column #6 widgets: ['zebra'] // prettify }); } @@ -43,9 +43,10 @@ function add() { function edit(id) { add_loading("#edit-button-" + id); add_loading("#delete-button-" + id); + var keyword = $('#keyword_'+id).val(); $.getJSON( "index_ajax.php", - { mode: "edit_display", id: id }, + { mode: "edit_display", keyword: keyword }, function(data){ $("#id-" + id).after( data.html ); $("#edit-url-"+ id).focus(); @@ -60,9 +61,10 @@ function remove(id) { if (!confirm('Really delete?')) { return; } + var keyword = $('#keyword_'+id).val(); $.getJSON( "index_ajax.php", - { mode: "delete", id: id }, + { mode: "delete", keyword: keyword }, function(data){ if (data.success == 1) { $("#id-" + id).fadeOut(function(){$(this).remove();zebra_table();}); @@ -85,15 +87,16 @@ function hide_edit(id) { function edit_save(id) { add_loading("#edit-close-" + id); var newurl = $("#edit-url-" + id).val(); - var newid = $("#edit-id-" + id).val(); + var newkeyword = $("#edit-keyword-" + id).val(); + var keyword = $('#old_keyword_'+id).val(); + var www = $('#yourls-site').val(); $.getJSON( "index_ajax.php", - {mode:'edit_save', url: newurl, id: id, newid: newid }, + {mode:'edit_save', url: newurl, keyword: keyword, newkeyword: newkeyword }, function(data){ if(data.status == 'success') { $("#url-" + id).html('' + data.url.url + ''); - $("#keyword-" + id).html(data.url.keyword); - $("#shorturl-" + id).html('' + data.url.shorturl + ''); + $("#keyword-" + id).html('' + data.url.shorturl + ''); $("#timestamp-" + id).html(data.url.date); $("#edit-" + id).fadeOut(200, function(){ $('#tblUrl tbody').trigger("update"); diff --git a/yourls-go.php b/yourls-go.php index 46d0529..e040f36 100644 --- a/yourls-go.php +++ b/yourls-go.php @@ -12,22 +12,17 @@ exit(); } -$id = yourls_sanitize_int( yourls_string2int($keyword) ); - // Get URL From Database -$table = YOURLS_DB_TABLE_URL; -$url = stripslashes($ydb->get_var("SELECT `url` FROM `$table` WHERE id = $id")); - -$protocol = $_SERVER["SERVER_PROTOCOL"]; -if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol ) - $protocol = 'HTTP/1.0'; - +$url = yourls_get_longurl( $keyword ); // URL found -if(!empty($url)) { - $update_clicks = $ydb->query("UPDATE `$table` SET `clicks` = clicks + 1 WHERE `id` = $id"); - header ($protocol.' 301 Moved Permanently'); - header ('Location: '. $url); +if( !empty($url) ) { + // Update click count in main table + $update_clicks = yourls_update_clicks( $keyword ); + // Update detailed log for stats + $log_redirect = yourls_log_redirect( $keyword ); + + yourls_redirect( $url, 301 ); // URL not found. Either reserved, or page, or doesn't exist } else { @@ -38,8 +33,7 @@ // Either reserved id, or no such id } else { - header ($protocol.' 307 Temporary Redirect'); // no 404 to tell browser this might change, and also to not pollute logs - header ('Location: '. YOURLS_SITE); + yourls_redirect( YOURLS_SITE, 307 ); // no 404 to tell browser this might change, and also to not pollute logs } } exit(); -- 2.45.0
Link ID  Original URL Short URLOriginal URL Date IP Clicks  
No URL Found
No URL Found
Edit: original URL:short URL: 
Original URL: Short URL: $www/ 
Invalid URL ID
Error, URL not found
$keyword$url$www/$keyword$date$ip $clicks 
$shorturl$url$date$ip$clicks