Created
August 10, 2010 20:32
-
-
Save peterdn/517938 to your computer and use it in GitHub Desktop.
PHP source used in my URL shortener (uses the CodeIgniter framework)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* Author: Peter Nelson / @_peterdn - controllers\url.php | |
* The main controller for the site. */ | |
class Url extends Controller | |
{ | |
public function Url() | |
{ | |
parent::Controller(); | |
$this->load->helper("url"); | |
} | |
public function index() | |
{ | |
$this->load->view("url_create"); | |
} | |
public function redirect() | |
{ | |
$subs = explode("/", uri_string()); | |
$slug = $subs[3]; | |
$this->load->model("Urls_table"); | |
$url = $this->Urls_table->getUrlForSlug($slug); | |
$this->Urls_table->incrementHits($slug); | |
if ($url) | |
{ | |
// Redirect to url or to a warning page, | |
// depending on the urls perceived reputation. | |
// Give the site the benefit of the doubt if we | |
// can get no information about it. | |
$rep = $this->_getUrlReputation($url); | |
if ($rep && is_array($rep)) | |
{ | |
$min = 100; | |
foreach ($rep as $name => $r) | |
$min = $min < $r["reputation"] ? $min : $r["reputation"]; | |
if ($min < 60) | |
redirect("/url/warning/$slug"); | |
} | |
header("location: $url"); | |
exit(); | |
} | |
else | |
{ | |
redirect("/"); | |
} | |
} | |
public function warning() | |
{ | |
$subs = explode("/", uri_string()); | |
$slug = $subs[3]; | |
$this->load->model("Urls_table"); | |
$url = $this->Urls_table->getUrlForSlug($slug); | |
if ($url) | |
{ | |
$rep = $this->_getUrlReputation($url); | |
$hostname = parse_url($url, PHP_URL_HOST); | |
$data = Array("slug" => $slug, "url" => $url, | |
"rep" => $rep, "hostname" => $hostname); | |
$this->load->view("url_warning", $data); | |
} | |
else | |
{ | |
redirect("/"); | |
} | |
} | |
public function create() | |
{ | |
$url = $this->input->post("url"); | |
$url = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED); | |
if (!$url) | |
redirect("/"); | |
$this->load->model("Urls_table"); | |
$n = 5; | |
$i = 0; | |
do | |
{ | |
$slug = $this->Urls_table->generateSlug($n); | |
if ($n < 10 && ++$i % 5 == 0) | |
++$n; | |
} | |
while ($this->Urls_table->doesSlugExist($slug)); | |
$date = new DateTime(); | |
$date = $date->format("Y-m-d H:i:s"); | |
$slug = $this->Urls_table->createUrlRow($url, $slug, $date, 0, 0); | |
redirect("/url/view/$slug"); | |
} | |
public function view() | |
{ | |
$slug = $this->uri->segment(3); | |
$this->load->model("Urls_table"); | |
if ($url = $this->Urls_table->getUrlForSlug($slug)) | |
{ | |
$rep = $this->_getUrlReputation($url); | |
$hostname = parse_url($url, PHP_URL_HOST); | |
$hits = $this->Urls_table->getHitsForSlug($slug); | |
$data = Array("slug" => $slug, "url" => $url, | |
"rep" => $rep, "hostname" => $hostname, "hits" => $hits); | |
$this->load->view("url_view", $data); | |
} | |
else | |
{ | |
redirect("/"); | |
} | |
} | |
public function privacy() | |
{ | |
$this->load->view("url_privacy"); | |
} | |
private function _getUrlReputation($url) | |
{ | |
// URL reputation data provided by WOT | |
// More info at http://www.mywot.com/wiki/API | |
$attributes = array(0 => "Trustworthiness", 1 => "Vendor reliability", | |
2 => "Privacy", 4 => "Child safety"); | |
$r = new HttpRequest("http://api.mywot.com/0.4/public_query2", | |
HttpRequest::METH_GET); | |
$r->setOptions(array("timeout" => 3)); | |
$r->addQueryData(array("url" => $url)); | |
try | |
{ | |
$r->send(); | |
if ($r->getResponseCode() == 200) | |
{ | |
// parse the XML response | |
$doc = new DOMDocument(); | |
$doc->loadXML($r->getResponseBody()); | |
$qs = $doc->getElementsByTagName("query"); | |
if (!$qs || $qs->length < 1) | |
return false; | |
$q = $qs->item(0); | |
$apps = $q->getElementsByTagName("application"); | |
if (!$apps) | |
return false; | |
$reps = array(); | |
$min = 100; | |
for ($i = 0; $i < $apps->length; ++$i) | |
{ | |
$a = $apps->item($i); | |
$name = (int)$a->attributes->getNamedItem("name")->nodeValue; | |
$rep = (int)$a->attributes->getNamedItem("r")->nodeValue; | |
$min = $min < $rep ? $min : $rep; | |
$conf = (int)$a->attributes->getNamedItem("c")->nodeValue; | |
$reps[$attributes[$name]] = array("reputation" => $rep, "confidence" => $conf); | |
} | |
return $reps; | |
} | |
} | |
catch (HttpException $ex) | |
{ | |
return false; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* Author: Peter Nelson / @_peterdn - models\urls_table.php | |
* Manages getting / setting url data to / from the database */ | |
class Urls_table extends Model | |
{ | |
public function Urls_table() | |
{ | |
parent::Model(); | |
$this->load->database(); | |
} | |
public function generateSlug($n) | |
{ | |
$slug = ""; | |
for ($i = 0; $i < $n; ++$i) | |
{ | |
$r = rand(0, 35); | |
$slug .= $r < 10 ? chr(48+$r) : chr(97+($r-10)); | |
} | |
return $slug; | |
} | |
public function getUrlForSlug($slug) | |
{ | |
$query = $this->db->query("SELECT url FROM urls WHERE slug=?", | |
array($slug)); | |
if ($query->num_rows() != 1) | |
return false; | |
if ($row = $query->row()) | |
return $row->url; | |
else | |
return false; | |
} | |
public function createUrlRow($url, $slug, $date, $hits, $flags) | |
{ | |
$existing = $this->getSlugForUrl($url); | |
if (!$existing) | |
{ | |
$this->db->query("INSERT INTO urls VALUES(?, ?, ?, ?, ?)", | |
array($url, $slug, $date, $hits, $flags)); | |
return $slug; | |
} | |
return $existing; | |
} | |
public function doesSlugExist($slug) | |
{ | |
$query = $this->db->query("SELECT id FROM urls WHERE slug=?", | |
array($slug)); | |
return $query->num_rows() == 1; | |
} | |
public function getHitsForSlug($slug) | |
{ | |
$query = $this->db->query("SELECT hits FROM urls WHERE slug=?", | |
array($slug)); | |
if ($query->num_rows() != 1) | |
return false; | |
$row = $query->row(); | |
return $row->hits; | |
} | |
public function incrementHits($slug) | |
{ | |
$hits = $this->getHitsForSlug($slug); | |
if ($hits === false) | |
return false; | |
++$hits; | |
$this->db->query("UPDATE urls SET hits=? WHERE slug=?", | |
array($hits, $slug)); | |
return $this->db->affected_rows() == 1; | |
} | |
public function getSlugForUrl($url) | |
{ | |
$q = "SELECT slug FROM urls WHERE url=?"; | |
$query = $this->db->query($q, array($url)); | |
if ($query->num_rows() < 1) | |
return false; | |
if ($row = $query->row()) | |
return $row->slug; | |
else | |
return false; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<title>pdn.to | URL shortener</title> | |
<meta charset="utf-8" /> | |
<link rel="shortcut icon" href="<?php echo THEMEPATH."/favicon.png"; ?>" type="image/png"/> | |
<style> | |
@import url('<?php echo THEMEPATH."/global.css"; ?>'); | |
</style> | |
<script src="<?php echo SCRIPTPATH."/glow/1.7.3/core/core.js"; ?>"></script> | |
<script src="<?php echo SCRIPTPATH."/qrcode.js"; ?>"></script> | |
<script src="<?php echo SCRIPTPATH."/buttons.js"; ?>"></script> | |
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]--> | |
</head> | |
<body> | |
<section id="main"> | |
<header> | |
<div style="text-align:center"><a href="http://pdn.to"><img src="<?php echo THEMEPATH."/logo.png"; ?>" alt="pdn.to | URL shortener" width="365" height="35" /></a></div> | |
</header> | |
<section id="createurl"> | |
<form method="post" action="/index.php/url/create"> | |
<p><input type="text" name="url" id="the_url" class="url" autocomplete="off" /></p> | |
<p><button type="submit" id="shorten" value="shorten">Shorten</button> | |
<button type="button" id="qrcode" value="qrcode">QR Code</button></p> | |
</form> | |
</section> | |
<section id="qrcode_info"> | |
<h2 id="qrcode_title"></h2> | |
<p id="qrcode_error" class="error"> | |
</p> | |
<p id="qrcode_container"> | |
<canvas id="qrcode_canvas"></canvas> | |
</p> | |
</section> | |
</section> | |
<footer> | |
<p><small>All content copyright © <a href="http://peterdn.com">Peter Nelson</a> 2010 | <a href="/index.php/url/privacy">Privacy Policy</a></small></p> | |
</footer> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<title>pdn.to | URL shortener</title> | |
<meta charset="utf-8" /> | |
<link rel="shortcut icon" href="<?php echo THEMEPATH."/favicon.png"; ?>" type="image/png"/> | |
<style> | |
@import url('<?php echo THEMEPATH."/global.css"; ?>'); | |
</style> | |
<script src="<?php echo SCRIPTPATH."/Silverlight.js"; ?>"></script> | |
<script src="<?php echo SCRIPTPATH."/glow/1.7.3/core/core.js"; ?>"></script> | |
<script src="<?php echo SCRIPTPATH."/qrcode.js"; ?>"></script> | |
<script src="<?php echo SCRIPTPATH."/buttons.js"; ?>"></script> | |
<script src="<?php echo SCRIPTPATH."/linkbox.js"; ?>"></script> | |
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]--> | |
</head> | |
<body> | |
<section id="main"> | |
<header> | |
<div style="text-align:center"><a href="http://pdn.to"><img src="<?php echo THEMEPATH."/logo.png"; ?>" alt="pdn.to | URL shortener" width="365" height="35" /></a></div> | |
</header> | |
<section id="createurl"> | |
<form method="post" action="/index.php/url/create"> | |
<div id="info"><p>Your Link:</p></div> | |
<div id="linkbox"><input type="text" id="the_url" class="yourlink" value="http://pdn.to/<?php echo $slug; ?>" readonly="readonly" /> | |
<div id="linkslbox"></div></div> | |
<div class="clear"></div> | |
<p><input type="text" name="url" class="url" autocomplete="off" value="<?php echo $url; ?>" /></p> | |
<p><button type="submit" name="op" id="shorten" value="shorten">Shorten</button> | |
<button type="button" name="op" id="qrcode" value="qrcode">QR Code</button></p> | |
</form> | |
</section> | |
<section id="qrcode_info"> | |
<h2 id="qrcode_title"></h2> | |
<p id="qrcode_error" class="error"> | |
</p> | |
<p id="qrcode_container"> | |
<canvas id="qrcode_canvas"></canvas> | |
</p> | |
</section> | |
<section id="url_reputation"> | |
<h2>Reputation of <?php echo $hostname; ?></h2> | |
<?php if ($rep) { ?> | |
<table> | |
<thead><tr><th>Description</th><th>Reputation<br />Estimate</th><th>Estimate<br />Reliability</th></tr></thead> | |
<?php | |
$n = 0; | |
$avg = 0; | |
foreach ($rep as $name => $data) | |
{ | |
++$n; | |
echo "<tr><td>$name</td><td>"; | |
$r = $data["reputation"]; | |
$avg += $r; | |
$c = $data["confidence"]; | |
if ($r < 20) echo "<span class=\"verypoor\">Very poor</span>"; | |
else if ($r >= 20 && $r < 40) echo "<span class=\"poor\">Poor</span>"; | |
else if ($r >= 40 && $r < 60) echo "<span class=\"unsatisfactory\">Unsatisfactory</span>"; | |
else if ($r >= 60 && $r < 80) echo "<span class=\"good\">Good</span>"; | |
else if ($r >= 80) echo "<span class=\"excellent\">Excellent</span>"; | |
echo "</td><td>"; | |
if ($c < 23) echo "<span class=\"unsatisfactory\">Uncertain</span>"; | |
else if ($c >= 23) echo "<span class=\"excellent\">Certain</span>"; | |
echo "</td></tr>"; | |
} | |
$avg /= $n; | |
echo "</table><p>Overall: <strong>"; | |
if ($avg < 20) echo "<span class=\"verypoor\">Very poor</span>"; | |
else if ($avg >= 20 && $avg < 40) echo "<span class=\"poor\">Poor</span>"; | |
else if ($avg >= 40 && $avg < 60) echo "<span class=\"unsatisfactory\">Unsatisfactory</span>"; | |
else if ($avg >= 60 && $avg < 80) echo "<span class=\"good\">Good</span>"; | |
else if ($avg >= 80) echo "<span class=\"excellent\">Excellent</span>"; | |
echo "</strong></p>"; | |
?> | |
<p>The table above provides information about this URL using data gathered by the <a href="http://www.mywot.com">Web of Trust (WOT)</a>. | |
It shows an estimate of how highly the website scores on each of four attributes, and a measure of how accurate each estimate is deemed to be.</p> | |
<?php } else { ?> | |
<p class="error">No reputation information available for this URL</p> | |
<?php } ?> | |
</section> | |
<section id="statistics"> | |
<h2>Statistics</h2> | |
<p>Total hits: <strong><?php echo $hits; ?></strong></p> | |
</section> | |
</section> | |
<footer> | |
<p><small>All content copyright © <a href="http://peterdn.com">Peter Nelson</a> 2010 | <a href="/index.php/url/privacy">Privacy Policy</a></small></p> | |
</footer> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<title>pdn.to | URL shortener</title> | |
<meta charset="utf-8" /> | |
<link rel="shortcut icon" href="<?php echo THEMEPATH."/favicon.png"; ?>" type="image/png"/> | |
<style> | |
@import url('<?php echo THEMEPATH."/global.css"; ?>'); | |
</style> | |
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]--> | |
</head> | |
<body> | |
<section id="main"> | |
<header> | |
<div style="text-align:center"><a href="http://pdn.to"><img src="<?php echo THEMEPATH."/logo.png"; ?>" alt="pdn.to | URL shortener" width="365" height="35" /></a></div> | |
</header> | |
<section id="url_reputation"> | |
<p class="warning">Warning: The website at <?php echo $hostname; ?> was deemed to be unsafe due to the reasons given below. | |
If you are certain that you wish to proceed, please <a href="<?php echo $url; ?>" rel="nofollow">follow this link</a>.</p> | |
<h2>Reputation of <?php echo $hostname; ?></h2> | |
<?php if ($rep) { ?> | |
<table> | |
<thead><tr><th>Description</th><th>Reputation<br />Estimate</th><th>Estimate<br />Reliability</th></tr></thead> | |
<?php | |
$n = 0; | |
$avg = 0; | |
foreach ($rep as $name => $data) | |
{ | |
++$n; | |
echo "<tr><td>$name</td><td>"; | |
$r = $data["reputation"]; | |
$avg += $r; | |
$c = $data["confidence"]; | |
if ($r < 20) echo "<span class=\"verypoor\">Very poor</span>"; | |
else if ($r >= 20 && $r < 40) echo "<span class=\"poor\">Poor</span>"; | |
else if ($r >= 40 && $r < 60) echo "<span class=\"unsatisfactory\">Unsatisfactory</span>"; | |
else if ($r >= 60 && $r < 80) echo "<span class=\"good\">Good</span>"; | |
else if ($r >= 80) echo "<span class=\"excellent\">Excellent</span>"; | |
echo "</td><td>"; | |
if ($c < 23) echo "<span class=\"unsatisfactory\">Uncertain</span>"; | |
else if ($c >= 23) echo "<span class=\"excellent\">Certain</span>"; | |
echo "</td></tr>"; | |
} | |
$avg /= $n; | |
echo "</table><p>Overall: <strong>"; | |
if ($avg < 20) echo "<span class=\"verypoor\">Very poor</span>"; | |
else if ($avg >= 20 && $avg < 40) echo "<span class=\"poor\">Poor</span>"; | |
else if ($avg >= 40 && $avg < 60) echo "<span class=\"unsatisfactory\">Unsatisfactory</span>"; | |
else if ($avg >= 60 && $avg < 80) echo "<span class=\"good\">Good</span>"; | |
else if ($avg >= 80) echo "<span class=\"excellent\">Excellent</span>"; | |
echo "</strong></p>"; | |
?> | |
<p>The table above provides information about this URL using data gathered by the <a href="http://www.mywot.com">Web of Trust (WOT)</a>. | |
It shows an estimate of how highly the website scores on each of four attributes, and a measure of how accurate each estimate is deemed to be.</p> | |
<?php } else { ?> | |
<p class="error">No reputation information available for this URL</p> | |
<?php } ?> | |
</section> | |
</section> | |
<footer> | |
<p><small>All content copyright © <a href="http://peterdn.com">Peter Nelson</a> 2010 | <a href="/index.php/url/privacy">Privacy Policy</a></small></p> | |
</footer> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Post about this here - http://peterdn.com/page/upeterdncom-URL-shortener.aspx