Got basic redirect working
This commit is contained in:
parent
f59bab2b4a
commit
d03bab8e02
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Shortlink;
|
||||
|
||||
class ShortlinkController extends Controller
|
||||
{
|
||||
public function create(Request $request) {
|
||||
if (auth()->user() == null) {
|
||||
return response()->json(['error' => 'Unauthorized'], 401);
|
||||
}
|
||||
|
||||
try {
|
||||
$request->validate([
|
||||
'url' => 'required|url'
|
||||
]);
|
||||
|
||||
//check if url returns 200 at its final redirect
|
||||
|
||||
$shortlink = new Shortlink();
|
||||
$shortlink->create($request->url, auth()->id());
|
||||
return redirect("/l/{$shortlink->shortid}");
|
||||
} catch (\Exception $e) {
|
||||
return back()->withErrors([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function goto(Request $request, $id) {
|
||||
try {
|
||||
$shortlink = (new Shortlink())->get($id);
|
||||
// check if the link is expired or if it has reached the max clicks
|
||||
// log the interaction
|
||||
return redirect($shortlink->destination);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => $e->getMessage()], 404);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Shortlink extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'shortid',
|
||||
'destination',
|
||||
'user_id',
|
||||
'max_clicks',
|
||||
'expires_at',
|
||||
];
|
||||
|
||||
public function create(string $url, int $user_id): Shortlink {
|
||||
$this->shortid = $this->generateNewId();
|
||||
$this->destination = $url;
|
||||
$this->user_id = $user_id;
|
||||
$this->max_clicks = 0;
|
||||
$this->expires_at = null;
|
||||
$this->save();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get(string $id): Shortlink {
|
||||
$shortlink = Shortlink::where('shortid', $id)->first();
|
||||
if ($shortlink == null) {
|
||||
throw new \Exception('This shortened link does not exist');
|
||||
}
|
||||
return $shortlink;
|
||||
}
|
||||
|
||||
public function delete(): void {
|
||||
Shortlink::where('shortid', $this->id)->delete();
|
||||
}
|
||||
|
||||
public function modify(int $max_clicks, $expires_at): void {
|
||||
$this->max_clicks = $max_clicks;
|
||||
$this->expires_at = $expires_at;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
function generateNewId(int $length = 6): string {
|
||||
$characters = 'qwrtypsdfghjklzxcvbnmQWRTYPSDFGHJKLZXCVBNM256789_';
|
||||
// try n x 2 times to generate a new id, if it finds an id, return it, otherwise, try to look for an id of length + 1
|
||||
for ($i = 0; $i < $length * 2; $i++) {
|
||||
$id = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$id .= $characters[rand(0, strlen($characters) - 1)];
|
||||
}
|
||||
if (Shortlink::where('shortid', $id)->count() == 0) {
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
return $this->generateNewId($length + 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('shortlinks', function (Blueprint $table) {
|
||||
$table->string('shortid')->unique()->primary();
|
||||
$table->string('destination');
|
||||
$table->foreignId('user_id')->references('id')->on('users');
|
||||
$table->integer('max_clicks')->default(0);
|
||||
$table->timestamp('expires_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('link_interactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('link');
|
||||
$table->foreign('link')->references('shortid')->on('shortlinks');
|
||||
$table->string('ip');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('shortlinks');
|
||||
Schema::dropIfExists('link_interactions');
|
||||
}
|
||||
};
|
|
@ -120,4 +120,45 @@ header nav a {
|
|||
background: #ff000028;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#shortener-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 60px 50px;
|
||||
background-color: var(--primary);
|
||||
width: calc(100% - 100px);
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
#shortener-container h1 {
|
||||
font-size: 2.5em;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#shortener-container input {
|
||||
color: black;
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
font-size: 1.3em;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px;
|
||||
border: 0;
|
||||
width: 600px;
|
||||
box-shadow: 2px 2px 5px 0 #0004;
|
||||
}
|
||||
|
||||
#shortener-container button {
|
||||
font-size: 1.3em;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
box-shadow: 2px 2px 5px 0 #0004;
|
||||
background-color: var(--foreground);
|
||||
}
|
||||
|
||||
#shortener-container input::placeholder {
|
||||
color: #aaa;
|
||||
}
|
|
@ -5,6 +5,21 @@
|
|||
@endsection
|
||||
|
||||
@section('content')
|
||||
<h1>HOMEPAGE!</h1>
|
||||
<p>Placeholder text</p>
|
||||
<div id="shortener-container">
|
||||
@if (auth()->check())
|
||||
<h1>Shorten your URL</h1>
|
||||
<form action="shorten" method="post">
|
||||
@csrf
|
||||
<input type="text" name="url" placeholder="Enter your URL here" required>
|
||||
<button type="submit">Shorten</button>
|
||||
</form>
|
||||
@if ($errors->any())
|
||||
<p class="error">{{ $errors->first() }}</p>
|
||||
@endif
|
||||
@else
|
||||
<h1>Welcome to slink URL Shortener</h1>
|
||||
<p><a href="register">Sign Up</a> or <a href="login">Log In</a> to shorten your URLs</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@endsection
|
|
@ -3,6 +3,7 @@
|
|||
use Illuminate\Support\Facades\Route;
|
||||
use App\Http\Controllers\RegisterController;
|
||||
use App\Http\Controllers\LoginController;
|
||||
use App\Http\Controllers\ShortlinkController;
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
|
@ -43,4 +44,10 @@ Route::get('/home', function () {
|
|||
return view('home');
|
||||
}
|
||||
return view('home');
|
||||
});
|
||||
});
|
||||
|
||||
Route::post('/shorten', [ShortlinkController::class, 'create']);
|
||||
|
||||
// Route::get('/l/{id}', );
|
||||
|
||||
Route::get('/{id}', [ShortlinkController::class, 'goto']);
|
Loading…
Reference in New Issue