Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit

  • Loading branch information...
commit 08cf12269b1bf60700b705d26fcaa613ba3c6c28 0 parents
@jfro authored
19 -/config.php
@@ -0,0 +1,19 @@
+<?php
+
+// LOGIN
+define('USERNAME', 'admin');
+define('PASSWORD', 'blarg');
+
+// DATABASE
+define('DB_NAME', 'bcurls');
+define('DB_USERNAME', 'bcurls');
+define('DB_PASSWORD', 'pass');
+
+// STATS!!! you can turn them off
+define('RECORD_URL_STATS', true);
+
+// FINE AS IS (UNLESS YOU KNOW OTHERWISE)
+define('DB_DRIVER', 'mysql'); // mysql or pgsql, sqlite could be done with maybe tweaks
+define('DB_SERVER', 'localhost');
+define('DB_PREFIX', 'bcurls_');
+define('COOKIE_SALT', 'B75sS4L7T0R3PEPp3R');
8 -/db.php
@@ -0,0 +1,8 @@
+<?php
+// no need to edit this file, see config.php
+ini_set('display_errors', 1);
+error_reporting(1);
+
+// connect
+$db = new PDO(DB_DRIVER.':host='.DB_SERVER.';dbname='.DB_NAME, DB_USERNAME, DB_PASSWORD);
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
103 -/index.php
@@ -0,0 +1,103 @@
+<?php
+
+include('config.php');
+include('db.php');
+include('stats.php');
+
+define('BCURLS_VERSION', '1.1');
+
+define('BCURLS_DOMAIN', preg_replace('#^www\.#', '', $_SERVER['SERVER_NAME']));
+define('BCURLS_URL', str_replace('-/index.php', '', 'http://'.BCURLS_DOMAIN.$_SERVER['PHP_SELF']));
+
+define('COOKIE_NAME', DB_PREFIX.'auth');
+define('COOKIE_VALUE', md5(USERNAME.PASSWORD.COOKIE_SALT));
+define('COOKIE_DOMAIN', '.'.BCURLS_DOMAIN);
+
+define('NOW', time());
+define('YEAR', 365 * 24 * 60 * 60);
+
+// handle login
+if (isset($_POST['username']))
+{
+ if (md5($_POST['username'].$_POST['password'].COOKIE_SALT) == COOKIE_VALUE)
+ {
+ setcookie(COOKIE_NAME, COOKIE_VALUE, NOW + YEAR, '/', COOKIE_DOMAIN);
+ $_COOKIE[COOKIE_NAME] = COOKIE_VALUE;
+ }
+}
+
+// handle logout
+if (isset($_GET['logout']))
+{
+ setcookie(COOKIE_NAME, '', NOW - YEAR, '/', COOKIE_DOMAIN);
+ unset($_COOKIE[COOKIE_NAME]);
+ header('Location:./');
+}
+
+// require login
+if (!isset($_COOKIE[COOKIE_NAME]) || $_COOKIE[COOKIE_NAME] != COOKIE_VALUE)
+{
+ include('pages/login.php');
+ exit();
+}
+// prolong login for another year
+else
+{
+ setcookie(COOKIE_NAME, COOKIE_VALUE, NOW + YEAR, '/', COOKIE_DOMAIN);
+}
+
+// new shortcut
+if (isset($_GET['url']) && !empty($_GET['url']))
+{
+ $url = $_GET['url'];
+ if (!preg_match('#^[^:]+://#', $url))
+ {
+ $url = 'http://'.$url;
+ }
+ $checksum = sprintf('%u', crc32($url));
+ $escaped_url = $url;
+ $result = $db->prepare('SELECT id FROM '.DB_PREFIX.'urls WHERE checksum=? AND url=? LIMIT 1');
+ $result->bindValue(1, (int)$checksum);
+ $result->bindValue(2, $escaped_url);
+ $result->execute();
+ if ($result->execute())
+ {
+
+ // exists
+ if ($row = $result->fetch(PDO::FETCH_ASSOC))
+ {
+ $id = $row['id'];
+ }
+ // create
+ else
+ {
+ if($_GET['custom_url'])
+ $custom_url = "'".$_GET['custom_url']."'";
+ else
+ $custom_url = "NULL";
+ $db->query('INSERT INTO '.DB_PREFIX.'urls (url, checksum, custom_url) VALUES(\''.$escaped_url.'\', '.$checksum.', '.$custom_url.')');
+ $id = $db->lastInsertId(DB_PREFIX."urls_id_seq");
+ }
+ }
+ if($_GET['custom_url'])
+ $new_url = BCURLS_URL.$_GET['custom_url'];
+ else
+ $new_url = BCURLS_URL.base_convert($id, 10, 36);
+
+ if (isset($_GET['tweet']))
+ {
+ header('Location:http://twitter.com/?status='.urlencode($new_url));
+ exit();
+ }
+ include('pages/done.php');
+}
+else if(isset($_GET['stats']))
+{
+ $top_urls = stats_top_urls($db);
+ $top_referers = stats_top_referers($db);
+ include('pages/stats.php');
+}
+else
+{
+ include('pages/add.php');
+}
26 -/pages/add.php
@@ -0,0 +1,26 @@
+<?php include('stubs/header.php'); ?>
+<form method="get">
+ <input type="text" id="url" name="url" placeholder="url" />
+ <button>Shrink URL</button> <br />
+ <input type="text" name="custom_url" value="" placeholder="custom short url" /> (optional)
+
+ <p>Grab the <a
+ title="Lessn a link"
+ href="javascript:location.href='<?php echo BCURLS_URL; ?>-/?url='+encodeURIComponent(location.href);"
+ onclick="alert('Drag this bookmarklet onto your browser bar.');return false;">
+ Shrinkn
+ </a> or <a
+ title="Lessn and tweet the Lessn'd link"
+ href="javascript:location.href='<?php echo BCURLS_URL; ?>-/?tweet&amp;url='+encodeURIComponent(location.href);"
+ onclick="alert('Drag this bookmarklet onto your browser bar.');return false;">
+ Tweetn
+ </a> bookmarklet.</p>
+</form>
+
+<p>
+ <a href="?stats=1">URL Stats</a>
+</p>
+<script>
+document.getElementById('url').focus();
+</script>
+<?php include('stubs/footer.php'); ?>
14 -/pages/done.php
@@ -0,0 +1,14 @@
+<?php include('stubs/header.php'); ?>
+<p>
+ <input type="text" id="url" value="<?php echo htmlspecialchars($new_url); ?>" onclick="this.focus();this.select();" readonly="readonly" />
+ → <strong><?php echo htmlspecialchars($url); ?></strong>
+</p>
+<p>
+ <a href="http://twitter.com/?status=<?php echo urlencode($new_url); ?>">Tweet</a>
+</p>
+<script>
+var input = document.getElementById('url');
+input.focus();
+input.select();
+</script>
+<?php include('stubs/footer.php'); ?>
10 -/pages/login.php
@@ -0,0 +1,10 @@
+<?php include('stubs/header.php'); ?>
+<form method="post">
+ <input type="text" name="username" placeholder="username" id="username" />
+ <input type="password" name="password" placeholder="password" />
+ <button>Login</button>
+</form>
+<script>
+document.getElementById('username').focus();
+</script>
+<?php include('stubs/footer.php'); ?>
37 -/pages/stats.php
@@ -0,0 +1,37 @@
+<?php include('stubs/header.php'); ?>
+<p>
+ <a href="/-/">Back</a>
+</p>
+<table border="0" cellspacing="0" cellpadding="10">
+ <tr>
+ <th>URL</th>
+ <th>Lessn'd</th>
+ <th>Hits</th>
+ </tr>
+
+<? foreach($top_urls as $url) { ?>
+<tr>
+ <td><?=$url['url']?></td>
+ <td><?=LESSN_URL.base_convert($url['id'], 10, 36);?></td>
+ <td><?=$url['hits']?></td>
+</tr>
+<? } ?>
+
+</table>
+
+<table border="0" cellspacing="0" cellpadding="10">
+ <tr>
+ <th>Referer</th>
+ <th>Hits</th>
+ </tr>
+
+<? foreach($top_referers as $url) { ?>
+<tr>
+ <td><?=$url['referer']?></td>
+ <td><?=$url['hits']?></td>
+</tr>
+<? } ?>
+
+</table>
+
+<?php include('stubs/footer.php'); ?>
22 -/stats.php
@@ -0,0 +1,22 @@
+<?php
+
+function record_stats($db, $url_id) {
+ $stmt = $db->prepare('INSERT INTO '.DB_PREFIX.'url_stats (url_id, ip_address, referer, created_on) VALUES(?,?,?,?)');
+ $stmt->bindValue(1, $url_id);
+ $stmt->bindValue(2, $_SERVER['REMOTE_ADDR']);
+ $stmt->bindValue(3, $_SERVER['HTTP_REFERER']);
+ $stmt->bindValue(4, date('Y-m-d H:i:s'));
+ $stmt->execute();
+}
+
+function stats_top_urls($db, $count=10) {
+ $stmt = $db->query('SELECT u.id,u.url,COUNT(s.url_id) as hits FROM '.DB_PREFIX.'urls u LEFT JOIN '.DB_PREFIX.'url_stats s ON u.id = s.url_id GROUP BY u.id,u.url ORDER BY hits desc LIMIT '.$count);
+ return $stmt->fetchAll(PDO::FETCH_ASSOC);
+}
+
+function stats_top_referers($db, $count=10) {
+ $query = 'SELECT s.referer,COUNT(s.referer) as hits FROM '.DB_PREFIX.'url_stats s WHERE s.referer IS NOT NULL GROUP BY s.referer ORDER BY hits DESC LIMIT '.$count;
+ $stmt = $db->query($query);
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ return $rows;
+}
2  -/stubs/footer.php
@@ -0,0 +1,2 @@
+</body>
+</html>
52 -/stubs/header.php
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<title>Lessn</title>
+<meta name="generator" content="ButteredURLs <?php echo BCURLS_VERSION;?>" />
+<style>
+body
+{
+ font-family: Helvetica, sans-serif;
+ text-align: center;
+ margin: 32px 0 0;
+ padding: 0;
+ color: #333;
+ background-color: #eee;
+}
+a,button
+{
+ display: inline-block;
+ border: none;
+ font-family: inherit;
+ font-weight: inherit;
+ font-size: 10px;
+ line-height: 16px;
+ height: 16px;
+ padding: 0 8px;
+ -webkit-border-radius: 8px;
+ -moz-border-radius: 8px;
+ border-radius: 8px;
+ cursor: pointer;
+ text-align: left;
+ text-decoration: none;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ vertical-align: middle;
+
+ color: #fff;
+ background-color: #333;
+}
+input
+{
+ font-family: inherit;
+ font-size: inherit;
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+ border: none;
+ padding: 4px;
+}
+</style>
+</head>
+<body>
6 .htaccess
@@ -0,0 +1,6 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine on
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule (.*) index.php?token=$1 [QSA,L]
+</IfModule>
20 CHANGES.txt
@@ -0,0 +1,20 @@
+1.1 (butteredurls fork)
+- modified query calls to use PDO to allow PostgreSQL/SQLite support
+- created an install.php to handle execution of installation queries
+- created statistics table to record IP/referer/timestamp
+- added column to urls table for doing custom urls like /flickr
+- added simple statistics (hits) page in admin area
+
+1.0.2
+- updated existing url query to also compare the url in the event of multiple matching checksums
+- changed UNIQUE checksum index to non-unique INDEX to allow for legitimate collisions
+- added note about .htaccess to README.txt
+- added "Updating from 1.0.1" to README.txt
+- added CHANGES.txt
+
+1.0.1
+- fixed YEAR definition (was 356 days instead of 365)
+- fixed typos in README.txt
+
+1.0
+- initial release
25 LICENSE.txt
@@ -0,0 +1,25 @@
+Copyright (c) 2009, Shaun Inman
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ of conditions and the following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ * Neither the Lessn name nor the names of its contributors may be used to endorse or
+ promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
8 README
@@ -0,0 +1,8 @@
+Buttered URLs
+=============
+
+Requirements
+-------------
+* PHP 5.1+
+* PHP's PDO
+* MySQL or PostgreSQL (SQLite added soon hopefully)
46 index.php
@@ -0,0 +1,46 @@
+<?php
+
+include('-/config.php');
+include('-/db.php');
+include('-/stats.php');
+
+$token = $_GET['token'];
+$show_stats = false;
+if(strrpos($token, '/stats'))
+{
+ $show_stats = true;
+}
+
+// redirect
+if (isset($_GET['token']))
+{
+ // try custom url first
+ $stmt = $db->query('SELECT * FROM '.DB_PREFIX.'urls WHERE custom_url=\''.$_GET['token'].'\' LIMIT 1');
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if(!$row)
+ {
+ $stmt = $db->query('SELECT * FROM '.DB_PREFIX.'urls WHERE id='.base_convert($_GET['token'], 36, 10).' LIMIT 1');
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+
+ if ($stmt)
+ {
+ if ($row)
+ {
+ if(RECORD_URL_STATS)
+ record_stats($db, $row['id']);
+ header($_SERVER['SERVER_PROTOCOL'].' 301 Moved Permanently');
+ header('Location:'.$row['url']);
+ exit();
+ }
+ }
+ else if($_GET['token'] == '')
+ exit('<h1>jfro.me</h1>');
+}
+else
+ exit('<h1>jfro.me</h1>');
+
+// no redirect
+header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
+header('Status:404');
+die('404 Not Found');
80 install.php
@@ -0,0 +1,80 @@
+<?php
+include('-/config.php');
+include('-/db.php');
+$prefix = DB_PREFIX;
+$sql = array();
+
+//$db_prefix = DB_PREFIX;
+$sql['pgsql'] = array();
+$sql['pgsql'][] = <<<EOT
+CREATE TABLE ${prefix}urls
+(
+ id serial NOT NULL,
+ url text NOT NULL,
+ checksum bigint NOT NULL,
+ CONSTRAINT lessn_urls_primary_key PRIMARY KEY (id)
+);
+EOT;
+
+$sql['pgsql'][] = <<<EOT
+CREATE TABLE ${prefix}url_stats
+(
+ id serial NOT NULL,
+ url_id integer NOT NULL,
+ ip_address inet,
+ referer text,
+ created_on timestamp without time zone NOT NULL,
+ CONSTRAINT ${prefix}url_stats_primary_key PRIMARY KEY (id),
+ CONSTRAINT url_id_fk FOREIGN KEY (url_id) REFERENCES ${prefix}urls (id) ON UPDATE NO ACTION ON DELETE CASCADE
+);
+EOT;
+
+$sql['pgsql'][] = <<<EOT
+ALTER TABLE ${prefix}urls ADD COLUMN custom_url varchar(255) DEFAULT NULL;
+EOT;
+
+// MySQL
+$sql['mysql'] = array();
+$sql['mysql'][] = <<<EOT
+CREATE TABLE ${prefix}urls(
+id int(11) unsigned NOT NULL auto_increment,
+url text character set utf8 collate utf8_unicode_ci NOT NULL,
+checksum int(10) unsigned NOT NULL,
+PRIMARY KEY (id),
+KEY checksum (checksum)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+EOT;
+
+$sql['mysql'][] = <<<EOT
+CREATE TABLE `${prefix}url_stats` (
+`id` int(11) unsigned NOT NULL auto_increment,
+`url_id` int(11) NOT NULL,
+`ip_address` varchar(255),
+`referer` varchar(255),
+`created_on` datetime,
+PRIMARY KEY (`id`),
+INDEX `url_id` (`url_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+EOT;
+
+$sql['mysql'][] = <<<EOT
+ALTER TABLE ${prefix}urls ADD COLUMN custom_url varchar(255) DEFAULT NULL;
+EOT;
+
+if(!array_key_exists(DB_DRIVER, $sql))
+ die('Unknown database driver, no installation SQL found');
+
+$queries = $sql[DB_DRIVER];
+if(isset($_GET['start']))
+{
+ $queries = array_slice($queries, $_GET['start']);
+ print 'Starting from query #'.$_GET['start'].'<br />';
+}
+
+foreach($queries as $q) {
+ //$q = str_replace("\n", "", $q);
+ // $stmt = $db->prepare($q);
+ // $stmt->execute();
+ $db->exec($q);
+}
+print 'Done, delete install.php';
Please sign in to comment.
Something went wrong with that request. Please try again.