initial commit

This commit is contained in:
Nils 2013-09-26 18:03:50 +02:00
commit 0306ab5dcd
310 changed files with 27490 additions and 0 deletions

13
.htaccess Normal file
View File

@ -0,0 +1,13 @@
RewriteEngine On
RewriteBase /
RewriteRule ^error[0-9]+\.html - [PT,L,QSA]
RewriteRule ^website/.* - [PT,L,QSA]
RewriteRule ^admin/.* - [PT,L,QSA]
RewriteRule ^api/(.*) - [PT,L,QSA]
RewriteRule ^api.php$ api/plain.php [QSA,L]
RewriteCond $0 !.+\.php$
RewriteRule ^([0-9a-z]+)(\.[a-z]+)? expand.php?id=$1&ext=$2
ErrorDocument 404 /error404.html
ErrorDocument 403 /error403.html
ErrorDocument 500 /error500.html

4
admin/.htaccess Normal file
View File

@ -0,0 +1,4 @@
AuthType Basic
AuthName "Service-Bereich"
AuthUserFile /var/www/mod4.cc/u/admin/.htusers
Require valid-user

2
admin/.htusers Normal file
View File

@ -0,0 +1,2 @@
jcoder:Fg3Ktv3chlhtA
jsilence:2/vwYRREnHZmc

74
admin/all-ids.php Normal file
View File

@ -0,0 +1,74 @@
<?php
include_once(dirname(__FILE__).'/../lib/functions.inc.php');
include_once(dirname(__FILE__).'/../lib/config.inc.php');
include_once(dirname(__FILE__).'/../lib/UrlShortener.class.php');
$urlShortener = new UrlShortener();
$linkData = $urlShortener->getStatsLinkData(-1);
echo "<" . "?xml version=\"1.0\"?".">\n";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener - Admin</title>
<link rel="stylesheet" href="reset.css" type="text/css" />
<link rel="stylesheet" href="style.1.css" type="text/css" />
<script src="../website/jquery-1.4.3.min.js" type="text/javascript"></script>
<script src="../website/jquery.cookie.js" type="text/javascript"></script>
</head>
<body>
<div id="header" class="pagearea">
<div class="contentblock">
&nbsp;
</div>
</div>
<div id="navigation" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
Navigation:
<a href="index.php" class="navlink">Overview</a>
<a href="all-ids.php" class="navlink hl">All IDs</a>
<a href="custom-ids.php" class="navlink">Custom IDs</a>
<a href="normal-ids.php" class="navlink">Normal IDs</a>
</div>
</div>
</div>
<div id="main" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
<?php
if (count($linkData) > 0) {
?>
<div class="captioned">All links:</div>
<table summary="all links">
<tr>
<th>Short ID</th>
<th>Long link</th>
<th>Last clicked at</th>
<th>Number of visits</th>
</tr>
<?php
for ($i = 0; $i < count($linkData); $i++) {
$oneLink = $linkData[$i];
?>
<tr>
<td><a href="<?= (SERVICE_BASE_URL . $oneLink['id']) ?>"><?= $oneLink['id'] ?></a></td>
<td><?= $oneLink['url'] ?></td>
<td><?= $oneLink['date'] ?></td>
<td><?= $oneLink['visited'] ?></td>
</tr>
<?php
}
?>
</table>
<?php
}
?>
</div>
</div>
</div>
</body>
</html>

74
admin/custom-ids.php Normal file
View File

@ -0,0 +1,74 @@
<?php
include_once(dirname(__FILE__).'/../lib/functions.inc.php');
include_once(dirname(__FILE__).'/../lib/config.inc.php');
include_once(dirname(__FILE__).'/../lib/UrlShortener.class.php');
$urlShortener = new UrlShortener();
$linkData = $urlShortener->getStatsLinkData(1);
echo "<" . "?xml version=\"1.0\"?".">\n";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener - Admin</title>
<link rel="stylesheet" href="reset.css" type="text/css" />
<link rel="stylesheet" href="style.1.css" type="text/css" />
<script src="../website/jquery-1.4.3.min.js" type="text/javascript"></script>
<script src="../website/jquery.cookie.js" type="text/javascript"></script>
</head>
<body>
<div id="header" class="pagearea">
<div class="contentblock">
&nbsp;
</div>
</div>
<div id="navigation" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
Navigation:
<a href="index.php" class="navlink">Overview</a>
<a href="all-ids.php" class="navlink">All IDs</a>
<a href="custom-ids.php" class="navlink hl">Custom IDs</a>
<a href="normal-ids.php" class="navlink">Normal IDs</a>
</div>
</div>
</div>
<div id="main" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
<?php
if (count($linkData) > 0) {
?>
<div class="captioned">All links:</div>
<table summary="all links">
<tr>
<th>Short ID</th>
<th>Long link</th>
<th>Last clicked at</th>
<th>Number of visits</th>
</tr>
<?php
for ($i = 0; $i < count($linkData); $i++) {
$oneLink = $linkData[$i];
?>
<tr>
<td><a href="<?= (SERVICE_BASE_URL . $oneLink['id']) ?>"><?= $oneLink['id'] ?></a></td>
<td><?= $oneLink['url'] ?></td>
<td><?= $oneLink['date'] ?></td>
<td><?= $oneLink['visited'] ?></td>
</tr>
<?php
}
?>
</table>
<?php
}
?>
</div>
</div>
</div>
</body>
</html>

96
admin/index.php Normal file
View File

@ -0,0 +1,96 @@
<?php
include_once(dirname(__FILE__).'/../lib/functions.inc.php');
include_once(dirname(__FILE__).'/../lib/config.inc.php');
include_once(dirname(__FILE__).'/../lib/UrlShortener.class.php');
$urlShortener = new UrlShortener();
$countByType = $urlShortener->getStatsCountByType();
$lastTenActive = $urlShortener->getStatsListActiveLinks(10);
echo "<" . "?xml version=\"1.0\"?".">\n";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener - Admin</title>
<link rel="stylesheet" href="reset.css" type="text/css" />
<link rel="stylesheet" href="style.1.css" type="text/css" />
<script src="../website/jquery-1.4.3.min.js" type="text/javascript"></script>
<script src="../website/jquery.cookie.js" type="text/javascript"></script>
</head>
<body>
<div id="header" class="pagearea">
<div class="contentblock">
&nbsp;
</div>
</div>
<div id="navigation" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
Navigation:
<a href="index.php" class="navlink hl">Overview</a>
<a href="all-ids.php" class="navlink">All IDs</a>
<a href="custom-ids.php" class="navlink">Custom IDs</a>
<a href="normal-ids.php" class="navlink">Normal IDs</a>
</div>
</div>
</div>
<div id="main" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
<?php
if ($countByType != NULL) {
?>
<div class="captioned">Number of links:</div>
<table summary="number of links">
<tr>
<td class="right">Number of links with <b>normal</b> short id:</td>
<td><b><?= $countByType[0]['cnt'] ?></b></td>
</tr>
<tr>
<td class="right">Number of links with <b>custom</b> short id:</td>
<td><b><?= $countByType[1]['cnt'] ?></b></td>
</tr>
<tr>
<td class="right"><b>Total</b> number of links:</td>
<td><b><?= ($countByType[0]['cnt'] + $countByType[1]['cnt']) ?></b></td>
</tr>
</table>
<?php
}
if (count($lastTenActive) > 0) {
?>
<div class="captioned">Last 10 active links:</div>
<table summary="last ten active links">
<tr>
<th>#</th>
<th>Short ID</th>
<th>Long link</th>
<th>Last clicked at</th>
<th>Number of visits</th>
</tr>
<?php
for ($i = 0; $i < count($lastTenActive); $i++) {
$oneLink = $lastTenActive[$i];
?>
<tr>
<td><?= $i ?></td>
<td><a href="<?= (SERVICE_BASE_URL . $oneLink['id']) ?>"><?= $oneLink['id'] ?></a></td>
<td><?= $oneLink['url'] ?></td>
<td><?= $oneLink['date'] ?></td>
<td><?= $oneLink['visited'] ?></td>
</tr>
<?php
}
?>
</table>
<?php
}
?>
</div>
</div>
</div>
</body>
</html>

74
admin/normal-ids.php Normal file
View File

@ -0,0 +1,74 @@
<?php
include_once(dirname(__FILE__).'/../lib/functions.inc.php');
include_once(dirname(__FILE__).'/../lib/config.inc.php');
include_once(dirname(__FILE__).'/../lib/UrlShortener.class.php');
$urlShortener = new UrlShortener();
$linkData = $urlShortener->getStatsLinkData(0);
echo "<" . "?xml version=\"1.0\"?".">\n";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener - Admin</title>
<link rel="stylesheet" href="reset.css" type="text/css" />
<link rel="stylesheet" href="style.1.css" type="text/css" />
<script src="../website/jquery-1.4.3.min.js" type="text/javascript"></script>
<script src="../website/jquery.cookie.js" type="text/javascript"></script>
</head>
<body>
<div id="header" class="pagearea">
<div class="contentblock">
&nbsp;
</div>
</div>
<div id="navigation" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
Navigation:
<a href="index.php" class="navlink">Overview</a>
<a href="all-ids.php" class="navlink">All IDs</a>
<a href="custom-ids.php" class="navlink">Custom IDs</a>
<a href="normal-ids.php" class="navlink hl">Normal IDs</a>
</div>
</div>
</div>
<div id="main" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
<?php
if (count($linkData) > 0) {
?>
<div class="captioned">All links:</div>
<table summary="all links">
<tr>
<th>Short ID</th>
<th>Long link</th>
<th>Last clicked at</th>
<th>Number of visits</th>
</tr>
<?php
for ($i = 0; $i < count($linkData); $i++) {
$oneLink = $linkData[$i];
?>
<tr>
<td><a href="<?= (SERVICE_BASE_URL . $oneLink['id']) ?>"><?= $oneLink['id'] ?></a></td>
<td><?= $oneLink['url'] ?></td>
<td><?= $oneLink['date'] ?></td>
<td><?= $oneLink['visited'] ?></td>
</tr>
<?php
}
?>
</table>
<?php
}
?>
</div>
</div>
</div>
</body>
</html>

53
admin/reset.css Normal file
View File

@ -0,0 +1,53 @@
/**
* CSS reset from
* http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
*
* removed: small, sup, sub, th, td, tr
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
strike, strong, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
vertical-align: baseline;
}
/* remember to define focus styles! */
:focus {
outline: 0;
}
body {
line-height: 1;
color: black;
background: white;
}
ol, ul {
list-style: none;
}
/* tables still need 'cellspacing="0"' in the markup */
table {
border-collapse: separate;
border-spacing: 0;
}
caption, th, td {
text-align: left;
font-weight: normal;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: "";
}
blockquote, q {
quotes: "" "";
}

187
admin/style.1.css Normal file
View File

@ -0,0 +1,187 @@
/**
*
*/
body {
font-family: Verdana, Helvetica, sans-serif;
font-size: 10pt;
color: #444444;
}
.italic {
font-style: italic;
}
.pagearea {
text-align: center;
}
.contentwidth {
width: 870px;
}
.right {
text-align: right;
}
#header {
}
#caption {
background-color: #b7caf8;
}
#main {
}
#features {
}
#options {
}
#featureinfo {
}
.contentblock {
width: 960px;
margin: 0 auto;
text-align: left;
}
#header .contentblock {
height: 50px;
text-align: right;
background-color: #f4f4f4;
}
#caption .contentblock {
height: 240px;
background-image: url(caption_bluesky.jpg);
text-align: right;
}
#caption .contentblock a {
font-size: 32pt;
color: #ffffff;
text-decoration: underline;
}
#main .contentblock {
margin-top: 10px;
background-color: #f4f4f4;
padding-bottom: 20px;
}
.formrow {
padding-bottom: 10px;
}
input.biginput {
font-size: 24pt;
}
input.mediuminput {
font-size: 16pt;
color: #888888;
}
button.bigbutton {
font-size: 24pt;
}
.errormsg {
padding: 8px;
font-size: 16pt;
color: #ff4c4c;
}
.result {
border: 1px solid #888888;
padding: 8px;
margin-bottom: 16px;
background-color: #ffffff;
}
.result strong {
font-weight: bold;
}
.result .longurl {
font-family: 'Courier New', Courier, monospace;
font-size: 12pt;
margin-bottom: 6px;
}
.result .shorturl {
font-family: 'Courier New', Courier, monospace;
font-size: 16pt;
margin-bottom: 6px;
}
#features .contentblock {
background-color: #f4f4f4;
margin-top: 10px;
}
#features .contentblock ul {
margin-left: 15px;
}
#features .contentblock li {
list-style-type: disc;
margin-left: 5px;
}
#options .contentblock {
margin-top: 10px;
background-color: #f4f4f4;
}
#featureinfo .contentblock {
margin-top: 10px;
background-color: #e1e7e7;
}
#featureinfo .contentblock ul {
margin-left: 15px;
}
#featureinfo .contentblock li {
list-style-type: disc;
margin-left: 5px;
margin-bottom: 8px;
}
#featureinfo .contentblock code {
font-family: 'Courier New', Courier, monospace;
}
#navigation {
}
#navigation .contentblock {
margin-top: 10px;
background-color: #f4f4f4;
padding-bottom: 20px;
}
#navigation .contentblock .navlink {
padding: 10px;
}
#navigation .contentblock .hl {
background-color: #e1e7e7;
}
#main .contentblock td,
#main .contentblock th {
border: 1px solid #888888;
padding: 5px;
}
#main .contentblock table {
border-collapse: collapse;
}
#main .contentblock .captioned {
letter-spacing: 0.15em;
font-style: italic;
font-size: 1.2em;
margin-top: 20px;
margin-bottom: 12px;
}

33
api/plain.php Normal file
View File

@ -0,0 +1,33 @@
<?php
include_once(dirname(__FILE__).'/../lib/config.inc.php');
include_once(dirname(__FILE__).'/../lib/functions.inc.php');
include_once(dirname(__FILE__).'/../lib/UrlShortener.class.php');
$urlShortener = new UrlShortener();
$urlParam = getRequestParameter("url");
header("Content-type: text/plain");
if (strlen($urlParam) == 0) {
echo "";
} else {
if (str_startswith($urlParam, SERVICE_BASE_URL) == true) {
// expand
$shortId = substr($urlParam, strlen(SERVICE_BASE_URL));
$expandedEntry = $urlShortener->expandUrl($shortId, true);
if ($expandedEntry != NULL) {
echo $expandedEntry['url'];
} else {
echo "";
}
} else {
// shorten
$shortId = $urlShortener->shortenUrl($urlParam, NULL);
if ($shortId != NULL) {
echo SERVICE_BASE_URL . $shortId;
} else {
echo "";
}
}
}

28
error403.html Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener - Error</title>
<style type="text/css">
<!--
body {
text-align: center;
}
#main {
width: 600px;
margin: 200px auto;
font-family: Georgia, 'Times New Roman', Times, sans-serif;
font-size: 32pt;
font-style: italic;
color: #888888;
}
//-->
</style>
</head>
<body>
<div id="main">
Error: the requested page could not be displayed.
</div>
</body>
</html>

28
error404.html Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener - Error</title>
<style type="text/css">
<!--
body {
text-align: center;
}
#main {
width: 600px;
margin: 200px auto;
font-family: Georgia, 'Times New Roman', Times, sans-serif;
font-size: 32pt;
font-style: italic;
color: #888888;
}
//-->
</style>
</head>
<body>
<div id="main">
Error: the requested page could not be displayed.
</div>
</body>
</html>

28
error500.html Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener - Error</title>
<style type="text/css">
<!--
body {
text-align: center;
}
#main {
width: 600px;
margin: 200px auto;
font-family: Georgia, 'Times New Roman', Times, sans-serif;
font-size: 32pt;
font-style: italic;
color: #888888;
}
//-->
</style>
</head>
<body>
<div id="main">
Error: the requested page could not be displayed.
</div>
</body>
</html>

90
expand.php Normal file
View File

@ -0,0 +1,90 @@
<?php
include_once(dirname(__FILE__).'/./lib/functions.inc.php');
include_once(dirname(__FILE__).'/./lib/UrlShortener.class.php');
include_once(dirname(__FILE__).'/./lib/Image/QRCode.php');
$urlShortener = new UrlShortener();
$shortid = getRequestParameter("id");
$shortext = getRequestParameter("ext");
if (str_startswith($shortext, ".") == true) {
$shortext = strtolower(substr($shortext, 1));
}
$calledUrl = SERVICE_BASE_URL . $shortid;
$expandedEntry = $urlShortener->expandUrl($shortid, true);
$warnCookie = false;
if (isset($_COOKIE['warn']) == true) {
$warnCookie = ($_COOKIE['warn'] == "true");
}
$resultCode = -1;
$resultMessage = NULL;
$resultUrl = NULL;
if ($expandedEntry == NULL) {
$resultCode = 404;
$resultMessage = "NOT_FOUND";
$resultUrl = NULL;
} else {
$resultCode = 200;
$resultMessage = "OK";
$resultUrl = $expandedEntry['url'];
}
if (($shortext == "text") || ($shortext == "txt") || ($shortext == "plain")) {
header("Content-type: text/plain");
echo $resultUrl;
exit;
}
if ($shortext == "json") {
// prevent caching
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
echo '{ "status_code": ' . $resultCode . ', "data": { "expand": [ { "short_url": "' . $calledUrl . '", "global_hash": "' . $shortid . '", "long_url": "' . $resultUrl . '", "user_hash": "' . $shortid . '" } ] }, "status_text": "' . $resultMessage . '" }';
exit;
}
if ($shortext == "xml") {
header("Content-type: application/xml");
echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>' . "\n";
echo '<response>' . "\n";
echo '<status_code>' . $resultCode . '</status_code>' . "\n";
echo '<status_txt>' . $resultMessage . '</status_txt>' . "\n";
echo '<data>' . "\n";
if ($resultCode == 200) {
echo '<entry>' . "\n";
echo ' <short_url>' . $calledUrl . '</short_url>' . "\n";
echo ' <long_url>' . $resultUrl . '</long_url>' . "\n";
echo ' <user_hash>' . $shortid . '</user_hash>' . "\n";
echo ' <global_hash>' . $shortid . '</global_hash>' . "\n";
echo '</entry>' . "\n";
}
echo '</data>' . "\n";
echo '</response>';
exit;
}
if (($shortext == "qrcode") || ($shortext == "qr")) {
header("Content-type: image/png");
$qr = new Image_QRCode();
$codeData = $calledUrl;
$qr->makeCode($codeData);
exit;
}
if ($resultCode == 200) {
if ($warnCookie == true) {
include('expand_warnpage.php');
} else {
header("Location: " . $resultUrl);
}
} else {
include('expand_notfound.php');
}
?>

82
expand_notfound.php Normal file
View File

@ -0,0 +1,82 @@
<?php
include_once(dirname(__FILE__).'/./lib/functions.inc.php');
include_once(dirname(__FILE__).'/./lib/config.inc.php');
include_once(dirname(__FILE__).'/./lib/UrlShortener.class.php');
echo "<" . "?xml version=\"1.0\"?".">\n";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener</title>
<link rel="stylesheet" href="website/reset.css" type="text/css" />
<link rel="stylesheet" href="website/style.1.css" type="text/css" />
<script src="website/jquery-1.4.3.min.js" type="text/javascript"></script>
<script src="website/jquery.cookie.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
var warningCookieEnabled = null;
$(document).ready(function() {
$('#warningcookie').show();
var warnCookieValue = $.cookie('warn');
if (warnCookieValue == null) {
warnCookieValue = "false";
}
warningCookieEnabled = warnCookieValue;
if (warnCookieValue == "true") {
$('#cookie_image').attr('src', 'website/16_accept.png');
$('#cookie_message').html('Warning enabled.');
$('#cookie_link').html('Click to disable warning.');
} else {
$('#cookie_image').attr('src', 'website/16_delete.png');
$('#cookie_message').html('Warning disabled.');
$('#cookie_link').html('Click to enable warning.');
}
});
function toggleWarning() {
if (warningCookieEnabled == "true") {
warningCookieEnabled = "false";
$.cookie('warn', 'false', { expires: 365, path: '/' });
$('#cookie_image').attr('src', 'website/16_delete.png');
$('#cookie_message').html('Warning disabled.');
$('#cookie_link').html('Click to enable warning.');
} else {
warningCookieEnabled = "true";
$.cookie('warn', 'true', { expires: 365, path: '/' });
$('#cookie_image').attr('src', 'website/16_accept.png');
$('#cookie_message').html('Warning enabled.');
$('#cookie_link').html('Click to disable warning.');
}
}
//-->
</script>
</head>
<body>
<div id="header" class="pagearea">
<div class="contentblock">
&nbsp;
</div>
</div>
<div id="caption" class="pagearea">
<div class="contentblock">
<div style="padding-top:170px;padding-right:30px;"><a href="index.php">URL Shortener</a></div>
</div>
</div>
<div id="main" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
<div class="errormsg">The requested short URL does not exist.</div>
</div>
</div>
</div>
<div id="footer" class="pagearea">
<div class="contentblock">
<div id="warningcookie" style="display:none;padding:20px;">
<img src="16_blank.png" id="cookie_image" alt="" /> <span id="cookie_message"></span> <a href="javascript:void(0);" id="cookie_link" onclick="toggleWarning();"></a>
</div>
</div>
</div>
</body>
</html>

86
expand_warnpage.php Normal file
View File

@ -0,0 +1,86 @@
<?php
include_once(dirname(__FILE__).'/./lib/functions.inc.php');
include_once(dirname(__FILE__).'/./lib/config.inc.php');
include_once(dirname(__FILE__).'/./lib/UrlShortener.class.php');
echo "<" . "?xml version=\"1.0\"?".">\n";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener</title>
<link rel="stylesheet" href="website/reset.css" type="text/css" />
<link rel="stylesheet" href="website/style.1.css" type="text/css" />
<script src="website/jquery-1.4.3.min.js" type="text/javascript"></script>
<script src="website/jquery.cookie.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
var warningCookieEnabled = null;
$(document).ready(function() {
$('#warningcookie').show();
var warnCookieValue = $.cookie('warn');
if (warnCookieValue == null) {
warnCookieValue = "false";
}
warningCookieEnabled = warnCookieValue;
if (warnCookieValue == "true") {
$('#cookie_image').attr('src', 'website/16_accept.png');
$('#cookie_message').html('Warning enabled.');
$('#cookie_link').html('Click to disable warning.');
} else {
$('#cookie_image').attr('src', 'website/16_delete.png');
$('#cookie_message').html('Warning disabled.');
$('#cookie_link').html('Click to enable warning.');
}
});
function toggleWarning() {
if (warningCookieEnabled == "true") {
warningCookieEnabled = "false";
$.cookie('warn', 'false', { expires: 365, path: '/' });
$('#cookie_image').attr('src', 'website/16_delete.png');
$('#cookie_message').html('Warning disabled.');
$('#cookie_link').html('Click to enable warning.');
} else {
warningCookieEnabled = "true";
$.cookie('warn', 'true', { expires: 365, path: '/' });
$('#cookie_image').attr('src', 'website/16_accept.png');
$('#cookie_message').html('Warning enabled.');
$('#cookie_link').html('Click to disable warning.');
}
}
//-->
</script>
</head>
<body>
<div id="header" class="pagearea">
<div class="contentblock">
&nbsp;
</div>
</div>
<div id="caption" class="pagearea">
<div class="contentblock">
<div style="padding-top:170px;padding-right:30px;"><a href="index.php">URL Shortener</a></div>
</div>
</div>
<div id="main" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
<div style="margin-bottom:20px;">You have enabled URL previews.</div>
<div class="result contentwidth">
<div class="shorturl"><a href="<?php echo $resultUrl; ?>">Click here to continue...</a></div>
<div class="longurl"><strong>URL:</strong> <?php echo $resultUrl; ?></div>
</div>
</div>
</div>
</div>
<div id="footer" class="pagearea">
<div class="contentblock">
<div id="warningcookie" style="display:none;padding:20px;">
<img src="16_blank.png" id="cookie_image" alt="" /> <span id="cookie_message"></span> <a href="javascript:void(0);" id="cookie_link" onclick="toggleWarning();"></a>
</div>
</div>
</div>
</body>
</html>

196
index.php Normal file
View File

@ -0,0 +1,196 @@
<?php
session_start();
include_once(dirname(__FILE__).'/./lib/functions.inc.php');
include_once(dirname(__FILE__).'/./lib/config.inc.php');
include_once(dirname(__FILE__).'/./lib/UrlShortener.class.php');
include_once(dirname(__FILE__).'/./lib/Captcha.class.php');
$msgError = NULL;
$msgLong = NULL;
$msgShort = NULL;
$urlShortener = new UrlShortener();
$captcha = new Captcha();
$longurl = getRequestParameter("longurl");
$plain = getRequestParameter("plain");
if (strlen($longurl) > 0) {
$captchaInput = getRequestParameter($_SESSION['CAPTCHA_FIELD']);
$captchaValid = false;
if (empty($captchaInput) == false) {
$captchaValid = $captcha->validateCaptcha($captchaInput);
}
if ($captchaValid == true) {
$shortId = $urlShortener->shortenUrl($longurl, $plain);
if ($shortId == NULL) {
$msgError = "The given URL could not be shortened.";
} else {
$msgShort = SERVICE_BASE_URL . $shortId;
$msgLong = $longurl;
$longurl = "";
}
} else {
$msgError = "Captcha invalid. Are sure you're not a bot?";
}
}
$displayCaptcha = $captcha->generateAndUseCaptcha();
$statsOverview = $urlShortener->getStatisticsOverview();
echo "<" . "?xml version=\"1.0\"?".">\n";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>URL Shortener</title>
<link rel="stylesheet" href="website/reset.css" type="text/css" />
<link rel="stylesheet" href="website/style.1.css" type="text/css" />
<script src="website/jquery-1.4.3.min.js" type="text/javascript"></script>
<script src="website/jquery.cookie.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
function enableOptionalForm() {
$("#optionalFormEnabler").hide();
$("#optionalFormData").show();
}
function preventDoubleSubmit() {
$("shortenUrlButton").disable();
}
var warningCookieEnabled = null;
$(document).ready(function() {
$('#warningcookie').show();
var warnCookieValue = $.cookie('warn');
if (warnCookieValue == null) {
warnCookieValue = "false";
}
warningCookieEnabled = warnCookieValue;
if (warnCookieValue == "true") {
$('#cookie_image').attr('src', 'website/16_accept.png');
$('#cookie_message').html('Warning enabled.');
$('#cookie_link').html('Click to disable warning.');
} else {
$('#cookie_image').attr('src', 'website/16_delete.png');
$('#cookie_message').html('Warning disabled.');
$('#cookie_link').html('Click to enable warning.');
}
});
function toggleWarning() {
if (warningCookieEnabled == "true") {
warningCookieEnabled = "false";
$.cookie('warn', 'false', { expires: 365, path: '/' });
$('#cookie_image').attr('src', 'website/16_delete.png');
$('#cookie_message').html('Warning disabled.');
$('#cookie_link').html('Click to enable warning.');
} else {
warningCookieEnabled = "true";
$.cookie('warn', 'true', { expires: 365, path: '/' });
$('#cookie_image').attr('src', 'website/16_accept.png');
$('#cookie_message').html('Warning enabled.');
$('#cookie_link').html('Click to disable warning.');
}
}
function show(elem) {
$('#'+elem).show();
var x = $('#'+elem).offset().top - 100; // 100 provides buffer in viewport
$('html,body').animate({scrollTop: x}, 500);
}
//-->
</script>
</head>
<body>
<div id="header" class="pagearea">
<div class="contentblock">
&nbsp;
</div>
</div>
<div id="caption" class="pagearea">
<div class="contentblock">
<div style="padding-top:170px;padding-right:30px;"><a href="index.php">URL Shortener</a></div>
</div>
</div>
<div id="main" class="pagearea">
<div class="contentblock">
<div style="padding:20px;">
<?php
if ($msgError != NULL) {
?>
<div class="errormsg"><?php echo $msgError; ?></div>
<?php
}
if (($msgLong != NULL) || ($msgShort != NULL)) {
?>
<div class="result contentwidth">
<div class="shorturl"><strong>Short URL:</strong> <?php echo $msgShort; ?></div>
<div class="longurl"><strong>Original URL:</strong> <?php echo $msgLong; ?></div>
</div>
<?php
}
?>
<form action="index.php" method="post">
<div class="formrow">URL to shorten</div>
<div class="formrow"><input type="text" name="longurl" value="<?php echo empty($longurl) ? "" : $longurl; ?>" class="biginput contentwidth" /></div>
<div class="formrow">Please answer: <?php echo $displayCaptcha; ?> <input type="text" name="<?php echo $_SESSION['CAPTCHA_FIELD']; ?>" value="" class="mediuminput" /></div>
<div class="formrow" id="optionalFormEnabler"><a href="javascript:void(0);" onclick="enableOptionalForm();">show optional information</a></div>
<div id="optionalFormData" style="display:none;">
<div class="formrow italic">optional: custum short id</div>
<div class="formrow"><input type="text" name="plain" value="" class="mediuminput" style="width:435px;" /></div>
</div>
<div class="formrow">
<button class="bigbutton" id="shortenUrlButton" name="shortenUrlButton" onclick="preventDoubleSubmit();" type="submit">Shorten URL!</button>
</div>
</form>
</div>
</div>
</div>
<div id="features" class="pagearea">
<div class="contentblock">
<div style="padding: 20px;">
Key features:
<ul>
<li>API and data structure compatible to urlShort (by mavrev.org)</li>
<li>extended API with different output formats like XML, JSON, plain text and even QR-Code images</li>
</ul>
<a href="javascript:void(0);" onclick="show('featureinfo');">see more infos...</a>
</div>
</div>
</div>
<div id="options" class="pagearea">
<div class="contentblock">
<div id="warningcookie" style="display:none;padding:20px;">
<img src="16_blank.png" id="cookie_image" alt="" /> <span id="cookie_message"></span> <a href="javascript:void(0);" id="cookie_link" onclick="toggleWarning();"></a>
<?php
if ($statsOverview != NULL) {
echo "<span style=\"margin-left:240px;font-style:italic;\">" . $statsOverview['count_ids'] . " links shortened, " . $statsOverview['sum_visited'] . " hits</span>";
}
?>
</div>
</div>
</div>
<div id="featureinfo" class="pagearea" style="display:none;">
<div class="contentblock">
<div style="padding: 20px;">
This Url Shortener provides the basic functions like shortening and expanding links.<br />
It is works on the same data structure and provides the same API (see <sup><small>*)</small></sup> below) as urlShort (by mavrev.org)<br />
You can enable a preview: if you visit a short URL, then you are not automatically redirected to the target page
but you get to see the full link and you can go here manually (this preview is set using a browser cookie).<br />
&nbsp;<br />
<b>API</b><br />
<ul>
<li>To expand <sup><small>*)</small></sup> a link:<br /><code><?php echo SERVICE_BASE_URL; ?>/api.php?url=<i><?php echo SERVICE_BASE_URL; ?>SHORT_ID</i></code></li>
<li>To expand a link and go to the web page:<br /><code><?php echo SERVICE_BASE_URL; ?><i>SHORT_ID</i></code></li>
<li>To expand a link to text:<br /><code><?php echo SERVICE_BASE_URL; ?><i>SHORT_ID.txt</i></code></li>
<li>To expand a link to xml:<br /><code><?php echo SERVICE_BASE_URL; ?><i>SHORT_ID.xml</i></code></li>
<li>To expand a link to json:<br /><code><?php echo SERVICE_BASE_URL; ?><i>SHORT_ID.json</i></code></li>
<li>To display a link as QR-Code (links to short URL):<br /><code><?php echo SERVICE_BASE_URL; ?><i>SHORT_ID.qr</i></code></li>
</ul>
</div>
</div>
</div>
<div>
&nbsp;
</div>
</body>
</html>

2
lib/.htaccess Normal file
View File

@ -0,0 +1,2 @@
Order deny, allow
Deny from all

View File

@ -0,0 +1,19 @@
<?php
/**
* Base class for storages
*/
abstract class AbstractStorage {
abstract function getEntryByUrl($url);
abstract function reserveId($userShortId, $url);
abstract function getEntryById($shortId);
abstract function markVisited($shortId);
abstract function getStatisticsOverview();
}

63
lib/Captcha.class.php Normal file
View File

@ -0,0 +1,63 @@
<?php
/**
* Captcha logic class
*/
include_once(dirname(__FILE__).'/./config.inc.php');
class Captcha {
private $calcOps;
function __construct() {
$this->calcOps = array("+", "-", "*");
}
function generateAndUseCaptcha() {
$rndType = rand(1, 100);
if ($rndType > 0) {
// build numeric question
$useOp = $this->calcOps[rand(0, 2)];
$firstNum = 0;
$secondNum = 0;
if ($useOp == "*") {
$firstNum = rand(0, 9);
$secondNum = rand(0, 15);
} else {
$firstNum = rand(0, 100);
$secondNum = rand(0, 100);
}
$calc = 0;
if ($useOp == "+") {
$calc = $firstNum + $secondNum;
} else if ($useOp == "-") {
$calc = $firstNum - $secondNum;
} else if ($useOp == "*") {
$calc = $firstNum * $secondNum;
}
$mathStr = "" . $firstNum . " " . $useOp . " " . $secondNum;
$_SESSION['CAPTCHA_QUESTION'] = $mathStr;
$_SESSION['CAPTCHA_VALUE'] = $calc;
// field name
$fieldname = chr(rand(65, 90)) . dechex(rand());
$_SESSION['CAPTCHA_FIELD'] = $fieldname;
return $mathStr;
} else {
// use pooled question
// TODO currently not supported due to missing logic which language to use
}
}
function validateCaptcha($inputStr) {
if (empty($inputStr) == true) {
return false;
}
if (isset($_SESSION['CAPTCHA_VALUE']) == false) {
return false;
}
$valueInSession = $_SESSION['CAPTCHA_VALUE'];
return ($inputStr == $valueInSession . "");
}
}

64
lib/IdIncreaser.class.php Normal file
View File

@ -0,0 +1,64 @@
<?php
/**
* Class to increase an ID
*/
class IdIncreaser {
private $chars = "0123456789abcdefghijklmnopqrstuvwxyz";
private $c = NULL;
function __construct($current, $alphabet = "") {
if (strlen($alphabet) > 0) {
$this->chars = $alphabet;
}
$this->c = new OneChar($current, $this->chars);
}
function increase() {
$this->c->increase();
}
function build() {
return $this->c->build();
}
}
class OneChar {
private $chars;
private $otherChar = NULL;
private $pos = 0;
function __construct($s, $ch) {
$this->chars = $ch;
$current = substr($s, -1, 1);
$this->pos = strpos($this->chars, $current);
$s = substr($s, 0, strlen($s)-1);
if (strlen($s) > 0) {
$this->otherChar = new OneChar($s, $ch);
}
}
function increase() {
$this->pos = $this->pos + 1;
if ($this->pos >= strlen($this->chars)) {
$this->pos = 0;
if ($this->otherChar != NULL) {
$this->otherChar->increase();
} else {
$this->otherChar = new OneChar($this->chars[0], $this->chars);
}
}
}
function build() {
if ($this->otherChar != NULL) {
return $this->otherChar->build() . $this->chars[$this->pos];
}
return $this->chars[$this->pos];
}
}

1407
lib/Image/QRCode.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
<?php
/**
* Image_QRCode - QR 2D barcode generator
*
* Image_QRCode - QR 2D barcode generator
*
* PHP version 5
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library in the file LICENSE.LGPL; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*
* @category Images
* @package Image_QRCode
* @author Y.Swetake <swe@venus.dti.ne.jp>
* @author Rich Sage <rich.sage@gmail.com>
* @copyright 2009 Y.Swetake
* @copyright 2009 R.Sage
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version SVN: $Id$
* @link http://code.google.com/p/pearqrcode/
*/
/**
* Base class for exceptions in PEAR
*/
require_once 'PEAR/Exception.php';
/**
* Image_QRCode_Exception
*
* @category Image
* @package Image_QRCode
* @author Y.Swetake <swe@venus.dti.ne.jp>
* @author Rich Sage <rich.sage@gmail.com>
* @license http://www.gnu.org/licenses/lgpl-2.1.txt GNU LGPL
* @version Release: 0.1
* @link http://code.google.com/p/pearqrcode/
*/
class Image_QRCode_Exception extends PEAR_Exception
{
}
?>

BIN
lib/Image/b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

BIN
lib/Image/d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

BIN
lib/Image/qrv1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

BIN
lib/Image/qrv10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

BIN
lib/Image/qrv11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

BIN
lib/Image/qrv12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

BIN
lib/Image/qrv13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

BIN
lib/Image/qrv14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

BIN
lib/Image/qrv15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

BIN
lib/Image/qrv16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

BIN
lib/Image/qrv17.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

BIN
lib/Image/qrv18.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

BIN
lib/Image/qrv19.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

BIN
lib/Image/qrv2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

BIN
lib/Image/qrv20.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

BIN
lib/Image/qrv21.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

BIN
lib/Image/qrv22.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

BIN
lib/Image/qrv23.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

BIN
lib/Image/qrv24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

BIN
lib/Image/qrv25.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

BIN
lib/Image/qrv26.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

BIN
lib/Image/qrv27.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

BIN
lib/Image/qrv28.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

BIN
lib/Image/qrv29.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

BIN
lib/Image/qrv3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

BIN
lib/Image/qrv30.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

BIN
lib/Image/qrv31.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

BIN
lib/Image/qrv32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

BIN
lib/Image/qrv33.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

BIN
lib/Image/qrv34.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

BIN
lib/Image/qrv35.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

BIN
lib/Image/qrv36.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

BIN
lib/Image/qrv37.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

BIN
lib/Image/qrv38.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

BIN
lib/Image/qrv39.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

BIN
lib/Image/qrv4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

BIN
lib/Image/qrv40.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

BIN
lib/Image/qrv5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

BIN
lib/Image/qrv6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

BIN
lib/Image/qrv7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

BIN
lib/Image/qrv8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

BIN
lib/Image/qrv9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

View File

@ -0,0 +1,188 @@
<?php
/**
* Storage using a database
*/
include_once(dirname(__FILE__).'/./config.inc.php');
include_once(dirname(__FILE__).'/./IdIncreaser.class.php');
include_once(dirname(__FILE__).'/./AbstractStorage.class.php');
class MySQLDbStorage extends AbstractStorage {
private $dbconn = NULL;
function __construct() {
try {
$this->dbconn = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_DATABASE, DB_USER, DB_PASS);
} catch (Exception $e) {
}
}
function __destruct() {
}
function getEntryByUrl($url) {
if ($this->dbconn == NULL) {
return NULL;
}
$sqlStr = "SELECT * FROM " . DB_TABLE . " WHERE url = :searchUrl AND text = 0";
$stmt = $this->dbconn->prepare($sqlStr, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute(array(':searchUrl' => $url));
$res = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $res;
}
function reserveId($userShortId, $url) {
if ($this->dbconn == NULL) {
return NULL;
}
$tmpId = $userShortId;
if ($tmpId != NULL) {
// try to allocate entry with that id
$sqlStr = "INSERT INTO " . DB_TABLE . " (id, url, text) VALUES (:insertId, :theUrl, 1)";
$stmt = $this->dbconn->prepare($sqlStr);
if (!$stmt->execute(array(':insertId' => $tmpId, ':theUrl' => $url))) {
// not successful, so set tmpId to null which generates a new id
$tmpId = NULL;
}
}
if ($tmpId == NULL) {
// find new unused id
$sqlStr = "SELECT id FROM " . DB_TABLE . " WHERE text = 0 ORDER BY date DESC LIMIT 1";
$stmt = $this->dbconn->prepare($sqlStr, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute();
$foundLastRes = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$foundLast = $foundLastRes['id'];
$idIncreaser = new IdIncreaser($foundLast, "");
$reservedId = NULL;
$sqlStr2 = "INSERT INTO " . DB_TABLE . " (id, url) VALUES (:reserveId, :theUrl)";
$stmt2 = $this->dbconn->prepare($sqlStr2);
do {
$idIncreaser->increase();
$nextId = $idIncreaser->build();
if ($stmt2->execute(array(':reserveId' => $nextId, ':theUrl' => $url))) {
$reservedId = $nextId;
}
} while ($reservedId == NULL);
$tmpId = $reservedId;
}
return $tmpId;
}
function getEntryById($shortId) {
if (empty($shortId) == true) {
return NULL;
}
if ($this->dbconn == NULL) {
return NULL;
}
$sqlStr = "SELECT * FROM " . DB_TABLE . " WHERE id = :searchId";
$stmt = $this->dbconn->prepare($sqlStr, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute(array(':searchId' => $shortId));
$foundRes = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $foundRes;
}
function markVisited($shortId) {
if (empty($shortId) == true) {
return;
}
if ($this->dbconn == NULL) {
return;
}
$sqlStr = "UPDATE urls SET visited = visited + 1 WHERE id = :visitedUrl";
$stmt = $this->dbconn->prepare($sqlStr);
$stmt->execute(array(':visitedUrl' => $shortId));
return;
}
function getStatisticsOverview() {
if ($this->dbconn == NULL) {
return NULL;
}
$sqlStr = "SELECT count(id) AS count_ids, sum(visited) AS sum_visited FROM urls";
$stmt = $this->dbconn->prepare($sqlStr, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute();
$foundRes = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $foundRes;
}
function getRandomLink() {
if ($this->dbconn == NULL) {
return NULL;
}
$sqlStr = "SELECT * FROM urls WHERE text = 0 ORDER by rand() LIMIT 1";
$stmt = $this->dbconn->prepare($sqlStr, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute();
$foundRes = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $foundRes;
}
function getStatsCountByType() {
if ($this->dbconn == NULL) {
return NULL;
}
$sqlStr = "SELECT count(id) AS cnt, text FROM urls GROUP BY text ORDER BY text";
$stmt = $this->dbconn->prepare($sqlStr, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute();
$res = $stmt->fetchAll();
$stmt->closeCursor();
if (count($res) != 2) {
return NULL;
}
return $res;
}
function getStatsAllLinksByType($t) {
if ($this->dbconn == NULL) {
return NULL;
}
$limitTo = "";
if ($t >= 0) {
$limitTo = "WHERE text = " . $t . " ";
}
$sqlStr = "SELECT * FROM urls " . $limitTo . "ORDER BY visited DESC";
$stmt = $this->dbconn->prepare($sqlStr, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute();
$res = $stmt->fetchAll();
$stmt->closeCursor();
return $res;
}
function getStatsListActiveLinks($cnt) {
if ($this->dbconn == NULL) {
return NULL;
}
$sqlStr = "SELECT * FROM urls ORDER BY date DESC LIMIT " . ($cnt+0);
$stmt = $this->dbconn->prepare($sqlStr, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute();
$res = $stmt->fetchAll();
$stmt->closeCursor();
return $res;
}
function getStatsLinkData($t) {
if ($this->dbconn == NULL) {
return NULL;
}
$limitTo = "";
if ($t >= 0) {
$limitTo = "WHERE text = " . $t . " ";
}
$sqlStr = "SELECT * FROM urls " . $limitTo . "ORDER BY visited DESC LIMIT 10000";
$stmt = $this->dbconn->prepare($sqlStr, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute();
$res = $stmt->fetchAll();
$stmt->closeCursor();
return $res;
}
}

107
lib/UrlShortener.class.php Normal file
View File

@ -0,0 +1,107 @@
<?php
/**
* URL Shortener logic
*/
include_once(dirname(__FILE__).'/./config.inc.php');
include_once(dirname(__FILE__).'/./MySQLDbStorage.class.php');
class UrlShortener {
private $storage;
function __construct() {
$this->storage = new MySQLDbStorage();
}
function shortenUrl($urlToShorten, $shortId = NULL) {
if (empty($urlToShorten) == true) {
return NULL;
}
if ($this->checkUrlPattern($urlToShorten) == false) {
return NULL;
}
if ($this->checkUserShortId($shortId) == false) {
$shortId = NULL;
}
// check if this url has been shortened before
$existingEntry = $this->storage->getEntryByUrl($urlToShorten);
if (empty($existingEntry) == false) {
if (empty($shortId) == true) {
return $existingEntry['id'];
}
if ($shortId == $existingEntry['id']) {
return $existingEntry['id'];
}
}
// assign URL
$newId = $this->storage->reserveId($shortId, $urlToShorten);
return $newId;
}
function expandUrl($urlToExpand, $markVisited = false) {
$shortUrl = $urlToExpand;
if (str_startswith($shortUrl, SERVICE_BASE_URL)) {
$shortUrl = substr($shortUrl, strlen(SERVICE_BASE_URL));
}
$foundEntry = $this->storage->getEntryById($shortUrl);
if (($foundEntry != NULL) && ($markVisited == true)) {
$this->storage->markVisited($foundEntry['id']);
// increase counter in object
$foundEntry['visited']++;
}
return $foundEntry;
}
function checkUrlPattern($urlToCheck) {
if (empty($urlToCheck) == true) {
return false;
}
$urlToCheck = strtolower($urlToCheck);
$supportedSchemas = array("http://", "https://", "mailto:");
foreach ($supportedSchemas as $oneSchema) {
if (str_startswith($urlToCheck, $oneSchema)) {
return true;
}
}
return false;
}
function checkUserShortId($shortidToCheck) {
// check pattern
if (preg_match("/[a-zA-Z0-9_-]+/", $shortidToCheck) != 1) {
return false;
}
// check against blacklist
// allow all short ids
return true;
}
function getStatisticsOverview() {
return $this->storage->getStatisticsOverview();
}
function getRandomLink() {
return $this->storage->getRandomLink();
}
function getStatsCountByType() {
return $this->storage->getStatsCountByType();
}
function getStatsAllLinksByType($t) {
return $this->storage->getStatsAllLinksByType($t);
}
function getStatsListActiveLinks($cnt = 10) {
return $this->storage->getStatsListActiveLinks($cnt);
}
function getStatsLinkData($t = -1) {
return $this->storage->getStatsLinkData($t);
}
}

12
lib/config.inc.php Normal file
View File

@ -0,0 +1,12 @@
<?php
/**
* configuration settings
*/
define('DB_HOST', '');
define('DB_USER', '');
define('DB_PASS', '');
define('DB_DATABASE', '');
define('DB_TABLE', 'urls');
define('SERVICE_BASE_URL', 'http://example.com/');

BIN
lib/data/qrv10_0.dat Normal file

Binary file not shown.

BIN
lib/data/qrv10_1.dat Normal file

Binary file not shown.

BIN
lib/data/qrv10_2.dat Normal file

Binary file not shown.

BIN
lib/data/qrv10_3.dat Normal file

Binary file not shown.

BIN
lib/data/qrv11_0.dat Normal file

Binary file not shown.

BIN
lib/data/qrv11_1.dat Normal file

Binary file not shown.

BIN
lib/data/qrv11_2.dat Normal file

Binary file not shown.

BIN
lib/data/qrv11_3.dat Normal file

Binary file not shown.

BIN
lib/data/qrv12_0.dat Normal file

Binary file not shown.

BIN
lib/data/qrv12_1.dat Normal file

Binary file not shown.

BIN
lib/data/qrv12_2.dat Normal file

Binary file not shown.

BIN
lib/data/qrv12_3.dat Normal file

Binary file not shown.

BIN
lib/data/qrv13_0.dat Normal file

Binary file not shown.

BIN
lib/data/qrv13_1.dat Normal file

Binary file not shown.

BIN
lib/data/qrv13_2.dat Normal file

Binary file not shown.

BIN
lib/data/qrv13_3.dat Normal file

Binary file not shown.

BIN
lib/data/qrv14_0.dat Normal file

Binary file not shown.

BIN
lib/data/qrv14_1.dat Normal file

Binary file not shown.

BIN
lib/data/qrv14_2.dat Normal file

Binary file not shown.

BIN
lib/data/qrv14_3.dat Normal file

Binary file not shown.

BIN
lib/data/qrv15_0.dat Normal file

Binary file not shown.

BIN
lib/data/qrv15_1.dat Normal file

Binary file not shown.

BIN
lib/data/qrv15_2.dat Normal file

Binary file not shown.

BIN
lib/data/qrv15_3.dat Normal file

Binary file not shown.

BIN
lib/data/qrv16_0.dat Normal file

Binary file not shown.

BIN
lib/data/qrv16_1.dat Normal file

Binary file not shown.

BIN
lib/data/qrv16_2.dat Normal file

Binary file not shown.

BIN
lib/data/qrv16_3.dat Normal file

Binary file not shown.

BIN
lib/data/qrv17_0.dat Normal file

Binary file not shown.

BIN
lib/data/qrv17_1.dat Normal file

Binary file not shown.

BIN
lib/data/qrv17_2.dat Normal file

Binary file not shown.

BIN
lib/data/qrv17_3.dat Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More