Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
realodix committed Jan 9, 2023
1 parent 5eec892 commit 1d9a18b
Show file tree
Hide file tree
Showing 17 changed files with 82 additions and 117 deletions.
1 change: 0 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost

UH_ANONYMIZE_IP_ADDR=true
UH_PUBLIC_SITE=true
UH_REGISTRATION=true
UH_HASH_LENGTH=6
Expand Down
1 change: 0 additions & 1 deletion .env.testing
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ APP_KEY=base64:SsuVzwH9xQnlEqSgTdTbBKyJ0rYrgt5Wr71vv02jDV8=
APP_DEBUG=true
APP_URL=http://localhost

UH_ANONYMIZE_IP_ADDR=true
UH_PUBLIC_SITE=true
UH_REGISTRATION=true
UH_HASH_LENGTH=6
Expand Down
15 changes: 0 additions & 15 deletions app/Helpers/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,9 @@
use Illuminate\Support\Str;
use Illuminate\Support\Stringable;
use Spatie\Url\Url as SpatieUrl;
use Symfony\Component\HttpFoundation\IpUtils;

class Helper
{
/**
* Anonymize an IPv4 or IPv6 address.
*
* @param string|null $address
*/
public static function anonymizeIp($address): string
{
if (config('urlhub.anonymize_ip_addr') === false) {
return $address;
}

return IPUtils::anonymize($address);
}

/**
* Display the link according to what You need.
*
Expand Down
14 changes: 6 additions & 8 deletions app/Http/Controllers/Dashboard/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Models\User;
use App\Services\DuplicateUrl;
use App\Services\KeyGeneratorService;
use App\Services\UpdateShortenedUrl;
use Illuminate\Http\Request;

class DashboardController extends Controller
Expand Down Expand Up @@ -34,12 +35,11 @@ public function view()
/**
* Show shortened url details page
*
* @param mixed $key
* @return \Illuminate\Contracts\View\View
*/
public function edit($key)
public function edit(string $urlKey)
{
$url = Url::whereKeyword($key)->first();
$url = Url::whereKeyword($urlKey)->first();

$this->authorize('updateUrl', $url);

Expand All @@ -50,16 +50,14 @@ public function edit($key)
* Update the destination URL
*
* @param Request $request \Illuminate\Http\Request
* @param mixed $url
* @param Url $url \App\Models\Url
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Request $request, $url)
public function update(Request $request, Url $url)
{
$url->destination = $request->long_url;
$url->title = $request->title;
$url->save();
app(UpdateShortenedUrl::class)->execute($request, $url);

return to_route('dashboard')
->withFlashSuccess(__('Link changed successfully !'));
Expand Down
22 changes: 4 additions & 18 deletions app/Http/Controllers/UrlController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace App\Http\Controllers;

use App\Helpers\Helper;
use App\Http\Requests\StoreUrl;
use App\Models\Url;
use App\Services\CreateShortenedUrl;
Expand All @@ -17,7 +16,6 @@ class UrlController extends Controller
*/
public function __construct(
public Url $url,
public KeyGeneratorService $keyGeneratorService,
) {
$this->middleware('urlhublinkchecker')->only('create');
}
Expand All @@ -30,18 +28,7 @@ public function __construct(
*/
public function create(StoreUrl $request)
{
$keyword = $request->custom_key ?? $this->keyGeneratorService->urlKey($request->long_url);
$isCustom = $request->custom_key ? true : false;

$data = [
'user_id' => auth()->id(),
'destination' => $request->long_url,
'title' => $request->long_url,
'keyword' => $keyword,
'is_custom' => $isCustom,
];

$url = app(CreateShortenedUrl::class)->execute($data);
$url = app(CreateShortenedUrl::class)->execute($request);

return to_route('su_detail', $url->keyword);
}
Expand All @@ -51,12 +38,11 @@ public function create(StoreUrl $request)
*
* @codeCoverageIgnore
*
* @param string $key
* @return \Illuminate\Contracts\View\View
*/
public function showDetail($key)
public function showDetail(string $urlKey)
{
$url = Url::with('visit')->whereKeyword($key)->firstOrFail();
$url = Url::with('visit')->whereKeyword($urlKey)->firstOrFail();
$data = ['url' => $url, 'visit' => new \App\Models\Visit];

if (config('urlhub.qrcode')) {
Expand Down Expand Up @@ -94,7 +80,7 @@ public function delete($url)
*/
public function duplicate(string $key)
{
$randomKey = $this->keyGeneratorService->generateRandomString();
$randomKey = app(KeyGeneratorService::class)->generateRandomString();
app(DuplicateUrl::class)->execute($key, auth()->id(), $randomKey);

return to_route('su_detail', $randomKey)
Expand Down
28 changes: 10 additions & 18 deletions app/Http/Controllers/UrlRedirectController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace App\Http\Controllers;

use App\Helpers\Helper;
use App\Models\Url;
use App\Services\UrlRedirection;
use App\Services\VisitorService;
Expand All @@ -11,6 +10,7 @@
class UrlRedirectController extends Controller
{
public function __construct(
public UrlRedirection $urlRedirection,
public VisitorService $visitorService,
) {
}
Expand All @@ -20,27 +20,19 @@ public function __construct(
* and executes the create visitor data task.
*
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\App\Models\Url>
*/
public function __invoke(UrlRedirection $urlRedirection, string $key)
public function __invoke(string $urlKey)
{
return DB::transaction(function () use ($urlRedirection, $key) {
$url = Url::whereKeyword($key)->firstOrFail();

$data = [
'url_id' => $url->id,
'is_first_click' => $this->visitorService->isFirstClick($url),
'referer' => request()->header('referer'),
'ip' => Helper::anonymizeIp(request()->ip()),
'browser' => \Browser::browserFamily(),
'browser_version' => \Browser::browserVersion(),
'device' => \Browser::deviceType(),
'os' => \Browser::platformFamily(),
'os_version' => \Browser::platformVersion(),
];
return DB::transaction(function () use ($urlKey) {
// firstOrFail() will throw a ModelNotFoundException if the URL is not
// found and 404 will be returned to the client.
$url = Url::whereKeyword($urlKey)->firstOrFail();

$this->visitorService->storeVisitorData($data);
$this->visitorService->create($url);

return $urlRedirection->execute($url);
return $this->urlRedirection->execute($url);
});
}
}
1 change: 1 addition & 0 deletions app/Models/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Url extends Model
'is_custom',
'destination',
'title',
'ip',
];

/**
Expand Down
33 changes: 24 additions & 9 deletions app/Services/CreateShortenedUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,36 @@

namespace App\Services;

use App\Http\Requests\StoreUrl;
use App\Models\Url;

class CreateShortenedUrl
{
/**
* @return \App\Models\Url
*/
public function execute(array $data)
public function __construct(
public KeyGeneratorService $keyGeneratorService,
) {
}

public function execute(StoreUrl $request): Url
{
return Url::create([
'user_id' => $data['user_id'],
'destination' => $data['destination'],
'title' => $data['title'],
'keyword' => $data['keyword'],
'is_custom' => $data['is_custom'],
'user_id' => auth()->id(),
'destination' => $request->long_url,
'title' => $request->long_url,
'keyword' => $this->urlKey($request),
'is_custom' => $this->isCustom($request),
'ip' => $request->ip(),
]);
}

private function urlKey(StoreUrl $request): string
{
return $request->custom_key ??
$this->keyGeneratorService->urlKey($request->long_url);
}

private function isCustom(StoreUrl $request): bool
{
return $request->custom_key ? true : false;
}
}
4 changes: 2 additions & 2 deletions app/Services/DuplicateUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ class DuplicateUrl
* @param int|string|null $userId \Illuminate\Contracts\Auth\Guard::id()
* @return bool \Illuminate\Database\Eloquent\Model::save()
*/
public function execute(string $key, $userId, string $randomKey = null)
public function execute(string $urlKey, $userId, string $randomKey = null)
{
$randomKey = $randomKey ?? app(KeyGeneratorService::class)->generateRandomString();
$shortenedUrl = Url::whereKeyword($key)->first();
$shortenedUrl = Url::whereKeyword($urlKey)->first();

$replicate = $shortenedUrl->replicate()->fill([
'user_id' => $userId,
Expand Down
2 changes: 1 addition & 1 deletion app/Services/KeyGeneratorService.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function assertStringCanBeUsedAsKey(string $value): bool
$routeCollection = \Illuminate\Support\Facades\Route::getRoutes()->get();
$routePath = array_map(fn ($route) => $route->uri, $routeCollection);

$isExistsInDb = Url::whereKeyword($value)->first();
$isExistsInDb = Url::whereKeyword($value)->exists();
$isReservedKeyword = in_array($value, config('urlhub.reserved_keyword'));
$isRegisteredRoutePath = in_array($value, $routePath);

Expand Down
20 changes: 20 additions & 0 deletions app/Services/UpdateShortenedUrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Services;

use App\Models\Url;
use Illuminate\Http\Request;

class UpdateShortenedUrl
{
/**
* @return bool
*/
public function execute(Request $request, Url $url)
{
return $url->update([
'destination' => $request->long_url,
'title' => $request->title,
]);
}
}
20 changes: 10 additions & 10 deletions app/Services/VisitorService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ class VisitorService
*
* @return void
*/
public function storeVisitorData(array $data)
public function create(Url $url)
{
$logBotVisit = config('urlhub.track_bot_visits');
if ($logBotVisit === false && \Browser::isBot() === true) {
return;
}

Visit::create([
'url_id' => $data['url_id'],
'url_id' => $url->id,
'visitor_id' => $this->visitorId(),
'is_first_click' => $data['is_first_click'],
'referer' => $data['referer'],
'ip' => $data['ip'],
'browser' => $data['browser'],
'browser_version' => $data['browser_version'],
'device' => $data['device'],
'os' => $data['os'],
'os_version' => $data['os_version'],
'is_first_click' => $this->isFirstClick($url),
'referer' => request()->header('referer'),
'ip' => request()->ip(),
'browser' => \Browser::browserFamily(),
'browser_version' => \Browser::browserVersion(),
'device' => \Browser::deviceType(),
'os' => \Browser::platformFamily(),
'os_version' => \Browser::platformVersion(),
]);
}

Expand Down
10 changes: 0 additions & 10 deletions config/urlhub.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,6 @@
|--------------------------------------------------------------------------
*/

/*
* Tells if IP addresses from visitors should be obfuscated before storing
* them in the database.
*
* Be careful!
* Setting this to false will make your UrlHub instance no longer be in
* compliance with the GDPR and other similar data protection regulations.
*/
'anonymize_ip_addr' => env('UH_ANONYMIZE_IP_ADDR', true),

/*
* Configure the kind of redirect you want to use for your short URLs. You
* can either set:
Expand Down
1 change: 1 addition & 0 deletions database/factories/UrlFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public function definition()
'title' => 'No Title',
'keyword' => app(KeyGeneratorService::class)->generateRandomString(),
'is_custom' => false,
'ip' => fake()->ipv4(),
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public function up()
$table->boolean('is_custom');
$table->longText('destination');
$table->string('title');
$table->ipAddress('ip');
$table->timestamps();
});
}
Expand Down
4 changes: 2 additions & 2 deletions database/migrations/2019_06_22_054239_create_visits_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public function up()
->cascadeOnDelete();
$table->string('visitor_id');
$table->boolean('is_first_click');
$table->string('referer', 300)->nullable()->default(0);
$table->ipAddress('ip');
$table->string('referer', 300)->nullable();
$table->ipAddress('ip')->nullable();
$table->string('browser')->nullable();
$table->string('browser_version')->nullable();
$table->string('device')->nullable();
Expand Down
Loading

0 comments on commit 1d9a18b

Please sign in to comment.