Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added some minor codes. #13

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
4 changes: 4 additions & 0 deletions .htaccess
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [QSA,L]
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ Shorty is a simple URL shortener for PHP.

3\. Configure your webserver.

For **Apache**, edit your `.htaccess` file with the following:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [QSA,L]

For **Nginx**, add the following to your server declaration:

server {
Expand Down
8 changes: 6 additions & 2 deletions config.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<?php
// Hostname for your URL shortener
$hostname = 'http://example.com';
//$hostname = 'https://shorty.techtook.xyz';
$hostname = 'http://shorty.loc';

// PDO connection to the database
$connection = new PDO('mysql:dbname=shorty;host=localhost', 'user', 'password');
$connection = new PDO('mysql:dbname=shorty;host=localhost', 'nahid', 'j');

// Choose your character set (default)
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
Expand All @@ -28,4 +29,7 @@
// The padding length to use when the salt value is configured above.
// The default value is 3.
$padding = 3;

//Set timezone
date_default_timezone_set('Asia/Dhaka');
?>
16 changes: 16 additions & 0 deletions create-new.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
require_once './header.php';
?>
<form action="">
<h3>Shorty</h3>
<div class="row">
<div class="form-group col-xs-9">
<input class="form-control input-lg" placeholder="http://example.com" name="url" type="url">
</div>
<div class="form-group col-xs-3">
<button type="submit" class="btn btn-info btn-lg">Shorten</button>
</div>
</div>
</form>

<?php require_once './footer.php' ?>
70 changes: 58 additions & 12 deletions database.sql
Original file line number Diff line number Diff line change
@@ -1,12 +1,58 @@
#
# Table schema for MySQL
#
CREATE TABLE urls (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
url VARCHAR(1000) NOT NULL,
created DATETIME NOT NULL,
accessed DATETIME,
hits INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id),
UNIQUE (url)
);

--
-- Table structure for table `hit_detail`
--

CREATE TABLE `hit_detail` (
`id` int(11) UNSIGNED NOT NULL,
`url_id` int(11) UNSIGNED NOT NULL,
`accessed` datetime NOT NULL,
`browser_name` varchar(63) NOT NULL,
`browser_version` varchar(63) NOT NULL,
`os` varchar(63) NOT NULL,
`ip` varchar(63) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Table structure for table `urls`
--

CREATE TABLE `urls` (
`id` int(10) UNSIGNED NOT NULL,
`url` varchar(1000) NOT NULL,
`created` datetime NOT NULL,
`accessed` datetime DEFAULT NULL,
`hits` int(10) UNSIGNED NOT NULL DEFAULT 0
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Indexes for table `hit_detail`
--
ALTER TABLE `hit_detail`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `urls`
--
ALTER TABLE `urls`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `url` (`url`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `hit_detail`
--
ALTER TABLE `hit_detail`
MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `urls`
--
ALTER TABLE `urls`
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
COMMIT;
5 changes: 5 additions & 0 deletions footer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

</div>

</body>
</html>
20 changes: 20 additions & 0 deletions header.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Shorty</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-item nav-link active" href="/">Home | </a>
<a class="nav-item nav-link" href="/hits.php"> Hits</a>
</div>
</div>
</nav>
40 changes: 40 additions & 0 deletions hits.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
require './config.php';
require './shorty.php';
require_once './header.php';

$shorty = new Shorty($hostname, $connection);

$statement = $connection->prepare(
'SELECT * FROM urls'
);
$statement->execute();
$urlViews = $statement->fetchAll(PDO::FETCH_ASSOC);
?>
<h3>URL Hits</h3>
<table class="table table-bordered">
<thead>
<tr>
<th>Short URL</th>
<th>Hits</th>
<th>Real URL</th>
<th>Created</th>
<th>Accessed</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($urlViews as $url){ ?>
<tr>
<td><?php echo '<a href="'.$hostname.'/'.$shorty->encode($url['id']).'" target="_blank">'.$hostname.'/'.$shorty->encode($url['id']).'</a>' ?></td>
<td class="p-3 mb-2 bg-info text-white"><?php echo $url['hits'] ?></td>
<td><?php echo $url['url'] ?></td>
<td><?php echo $url['created'] ?></td>
<td><?php echo $url['accessed'] ?></td>
<td><?php echo '<a href="'.$hostname.'/visitor-detail.php?id='.$url['id'].'">Visitor Detail</a>' ?></td>
</tr>
<?php } ?>
</tbody>
</table>

<?php require_once './footer.php' ?>
5 changes: 5 additions & 0 deletions result.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php
require_once './header.php';
?>
<h3>Your Short URL</h3>
<?php echo "<a href='$url' target='_blank'>$url</a>" ?>
22 changes: 19 additions & 3 deletions shorty.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,16 @@ public function update($id) {
'UPDATE urls SET hits = hits + 1, accessed = ? WHERE id = ?'
);
$statement->execute(array($datetime, $id));

include 'src/VisitorTracking.php';

$visitor = new VisitorTracking();
$browser = $visitor->browser;

$statement = $this->connection->prepare(
'INSERT INTO hit_detail (url_id, accessed, browser_name, browser_version, os, ip) VALUES (?,?,?,?,?,?)'
);
$statement->execute(array($id, $datetime, $browser->name, $browser->version, $browser->OS, $visitor->ip));
}

/**
Expand Down Expand Up @@ -311,7 +321,7 @@ public function allow($ip) {
* Starts the program.
*/
public function run() {
$q = str_replace('/', '', $_GET['q']);


$url = '';
if (isset($_GET['url'])) {
Expand Down Expand Up @@ -362,15 +372,17 @@ public function run() {
)));

default:
exit('<a href="'.$url.'">'.$url.'</a>');
include_once './result.php';
// exit('<a href="'.$url.'">'.$url.'</a>');
}
}
else {
$this->error('Bad input.');
}
}
// Lookup by id
else {
elseif (isset($_GET['q'])) {
$q = str_replace('/', '', $_GET['q']);
if (empty($q)) {
$this->not_found();
return;
Expand All @@ -391,5 +403,9 @@ public function run() {
}
}
}
//Show form to create the short URL
else{
include_once 'create-new.php';
}
}
}
131 changes: 131 additions & 0 deletions src/VisitorTracking.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

class VisitorTracking
{
/** @var null|\stdClass $browser */
public $browser = null;
/** @var \Closure|null */
private $error_handler = null;

/**
* Stalk constructor.
*
* @param \Closure|null $error_handler
* @param string|null $ip
*/
public function __construct(Closure $error_handler = null, string $ip = null)
{
$this->ip = $ip == null ? $this->getIp() : $ip;
$this->error_handler = $error_handler;
$this->browser = (object) $this->getBrowser();
}

/**
* Gets clients IP address.
*
* @return string
*/
private function getIp(): string
{
$client = @$_SERVER['HTTP_CLIENT_IP'];
$forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
$remote = $_SERVER['REMOTE_ADDR'];

if (filter_var($client, FILTER_VALIDATE_IP)) {
$ip = $client;
}
elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
$ip = $forward;
}
else {
$ip = $remote;
}

return $ip;
}

/**
* Gets clients browser's information.
*
* @return array
*/
private function getBrowser(): array
{
$u_agent = $_SERVER['HTTP_USER_AGENT'];
$platform = 'Unknown';
$browser_name = 'Unknown';
$version = null;

if (preg_match('/linux/i', $u_agent)) {
$platform = 'linux';
}
elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
$platform = 'mac';
}
elseif (preg_match('/windows|win32/i', $u_agent)) {
$platform = 'windows';
}
if (preg_match('/MSIE/i', $u_agent) && ! preg_match('/Opera/i', $u_agent)) {
$browser_name = 'Internet Explorer';
$ub = "MSIE";
}
elseif (preg_match('/Firefox/i', $u_agent)) {
$browser_name = 'Mozilla Firefox';
$ub = "Firefox";
}
elseif (preg_match('/Chrome/i', $u_agent)) {
$browser_name = 'Google Chrome';
$ub = "Chrome";
}
elseif (preg_match('/Safari/i', $u_agent)) {
$browser_name = 'Apple Safari';
$ub = "Safari";
}
elseif (preg_match('/Opera/i', $u_agent)) {
$browser_name = 'Opera';
$ub = "Opera";
}
elseif (preg_match('/Netscape/i', $u_agent)) {
$browser_name = 'Netscape';
$ub = "Netscape";
}

$known = ['Version', $ub, 'other'];
$join = implode('|', $known);
$pattern = '#(?<browser>' . $join . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';

preg_match_all($pattern, $u_agent, $matches);
$i = count($matches['browser']);

if ($i != 1) {
if (strripos($u_agent, 'Version') < strripos($u_agent, $ub)) {
$version = $matches['version'][0];
}
else {
$version = $matches['version'][1];
}
}
else {
$version = $matches['version'][0];
}

if (! $version) {
$version = '?';
}

return ['name' => $browser_name, 'version' => $version, 'OS' => $platform];
}

/**
* Key value pair of all stack attribute.
*
* @return array
*/
public function __toArray(): array
{
$properties = get_object_vars($this);
$properties['browser'] = (array) $properties['browser'];

return $properties;
}
}
Loading