From 3166710510a739301d62a4c8870ed4fe827b19f0 Mon Sep 17 00:00:00 2001 From: A1Gard Date: Tue, 16 Jul 2024 12:51:52 +0330 Subject: [PATCH] optimized visitor model, migration, middleware, seeder --- app/Helpers/TVisitor.php | 133 ++---------------- ...VisitorDetector.php => VisitorCounter.php} | 17 ++- app/Models/Visitor.php | 71 ++++++++++ database/factories/VisitorFactory.php | 30 +++- ...024_07_16_042925_create_visitors_table.php | 6 +- database/seeders/VisitorSeeder.php | 2 +- routes/web.php | 6 +- 7 files changed, 120 insertions(+), 145 deletions(-) rename app/Http/Middleware/{VisitorDetector.php => VisitorCounter.php} (66%) diff --git a/app/Helpers/TVisitor.php b/app/Helpers/TVisitor.php index f2c436d..ab8d7eb 100644 --- a/app/Helpers/TVisitor.php +++ b/app/Helpers/TVisitor.php @@ -2,6 +2,8 @@ namespace App\Helpers; +use App\Models\Visitor; + /** * @package Helpers * @author A1Gard @@ -25,45 +27,7 @@ class TVisitor { if (!isset($_SERVER['HTTP_USER_AGENT'])) return 0; - $os_list = array( - '(Linux)', - '(Windows NT 11.0)', // Added Windows 11 - '(Windows NT 10.0)', - '(Windows NT 6.3)', - '(Windows NT 6.2)', - '(Windows NT 6.1)', - '(Windows NT 6.0)', - '(Windows NT 5.2)', - '(Windows NT 5.1)', - '(Windows NT 5.0)', - '(Windows NT 4.0)', - '(Win 9x 4.90)', - '(Windows 98)', - '(Windows 95)', - '(Windows CE)', - 'Windows (iPhone|iPad)', - '(iPhone)|(iPad)', - '(Mac OS X)', - '(MacPPC)|(Mac_PowerPC)|(Macintosh)', - '(Ubuntu)', - '(Linux Mint)', - '(Debian)', - '(Fedora)', - '(Red Hat)', - '(SuSE)', - '(Android)', - '(webOS)|(hpwOS)', - '(BlackBerry)', - '(Symbian)', - '(FreeBSD)', - '(OpenBSD)', - '(NetBSD)', - '(SunOS)', - '(OpenSolaris)', - '(Chrome OS)', - '(CrOS)', - '(bot)' - ); + $os_list = array_values(Visitor::$osList); foreach ($os_list as $index => $match) { if (preg_match("/$match/i", $_SERVER['HTTP_USER_AGENT'])) { @@ -82,43 +46,7 @@ class TVisitor { if (!isset($_SERVER['HTTP_USER_AGENT'])) return 'Unknown'; - $os_list = array( - 'Linux' => '(Linux)', - 'Windows 11' => '(Windows NT 11.0)', // Added Windows 11 - 'Windows 10' => '(Windows NT 10.0)', - 'Windows 8.1' => '(Windows NT 6.3)', - 'Windows 8' => '(Windows NT 6.2)', - 'Windows 7' => '(Windows NT 6.1)', - 'Windows Vista' => '(Windows NT 6.0)', - 'Windows Server 2003/XP x64' => '(Windows NT 5.2)', - 'Windows XP' => '(Windows NT 5.1)', - 'Windows 2000' => '(Windows NT 5.0)', - 'Windows ME' => '(Win 9x 4.90)', - 'Windows 98' => '(Windows 98)', - 'Windows 95' => '(Windows 95)', - 'Windows CE' => '(Windows CE)', - 'Windows (iPhone/iPad)' => 'Windows (iPhone|iPad)', - 'iPhone/iPad' => '(iPhone)|(iPad)', - 'Mac OS X' => '(Mac OS X)', - 'Mac OS' => '(MacPPC)|(Mac_PowerPC)|(Macintosh)', - 'Ubuntu' => '(Ubuntu)', - 'Linux Mint' => '(Linux Mint)', - 'Debian' => '(Debian)', - 'Fedora' => '(Fedora)', - 'Red Hat' => '(Red Hat)', - 'SuSE' => '(SuSE)', - 'Android' => '(Android)', - 'webOS' => '(webOS)|(hpwOS)', - 'BlackBerry' => '(BlackBerry)', - 'Symbian' => '(Symbian)', - 'FreeBSD' => '(FreeBSD)', - 'OpenBSD' => '(OpenBSD)', - 'NetBSD' => '(NetBSD)', - 'SunOS' => '(SunOS)', - 'OpenSolaris' => '(OpenSolaris)', - 'Chrome OS' => '(Chrome OS)|(CrOS)', - 'bot' => '(bot)' - ); + $os_list = Visitor::$osList; foreach ($os_list as $os => $pattern) { if (preg_match("/$pattern/i", $_SERVER['HTTP_USER_AGENT'])) { @@ -145,7 +73,7 @@ class TVisitor { 'mobile', 'android', 'iphone', 'ipod', 'ipad', 'windows phone', 'blackberry', 'kindle', 'silk', 'opera mini', 'opera mobi', 'webos', 'symbian', 'nokia', 'samsung', 'lg', 'htc', 'mot', 'tablet', 'rim tablet', 'meego', 'netfront', 'bolt', 'fennec', 'series60', 'maemo', 'midp', 'cldc', 'up.browser', - 'up.link', 'mmp', 'symbian', 'smartphone', 'wap' + 'up.link', 'mmp', 'symbian', 'smartphone', 'wap', ]; // Check if user agent contains any mobile keywords @@ -192,24 +120,7 @@ class TVisitor { if (!isset($_SERVER['HTTP_USER_AGENT'])) return 'Unknown'; - $browser_list = array( - 'Firefox' => '(Firefox)', - 'Edge' => '(Edg|Edge)', - 'Chrome' => '(Chrome)(?!.*Edge)', - 'Safari' => '(Safari)(?!.*Chrome)', - 'Opera' => '(OPR|Opera)', - 'Brave' => '(Brave)', - 'Internet Explorer' => '(MSIE|Trident)', - 'DeepNet Explorer' => '(Deepnet)', - 'Flock' => '(Flock)', - 'Maxthon' => '(Maxthon)', - 'Avant Browser' => '(Avant)', - 'AOL' => '(AOL)', - 'Vivaldi' => '(Vivaldi)', - 'UC Browser' => '(UCBrowser)', - 'Yandex Browser' => '(YaBrowser)', - 'Samsung Internet' => '(SamsungBrowser)', - ); + $browser_list = Visitor::$browserList; foreach ($browser_list as $browser => $pattern) { if (preg_match("/$pattern/i", $_SERVER['HTTP_USER_AGENT'])) { @@ -228,24 +139,7 @@ class TVisitor { if (!isset($_SERVER['HTTP_USER_AGENT'])) return 0; - $browser_list = array( - '(Firefox)', - '(Edg|Edge)', - '(Chrome)(?!.*Edge)', - '(Safari)(?!.*Chrome)', - '(OPR|Opera)', - '(Brave)', - '(MSIE|Trident)', - '(Deepnet)', - '(Flock)', - '(Maxthon)', - '(Avant)', - '(AOL)', - '(Vivaldi)', - '(UCBrowser)', - '(YaBrowser)', - '(SamsungBrowser)', - ); + $browser_list = array_values(Visitor::$browserList); foreach ($browser_list as $index => $pattern) { if (preg_match("/$pattern/i", $_SERVER['HTTP_USER_AGENT'])) { @@ -328,18 +222,7 @@ class TVisitor { return null; } - $engines = [ - 'google' => ['q', 'query'], - 'bing' => ['q'], - 'yahoo' => ['p'], - 'yandex' => ['text'], - 'baidu' => ['wd', 'word'], - 'duckduckgo' => ['q'], - 'ask' => ['q'], - 'aol' => ['q'], - 'naver' => ['query'], - 'ecosia' => ['q'], - ]; + $engines = Visitor::$engines; $parsed_url = parse_url($referer); $host = isset($parsed_url['host']) ? strtolower($parsed_url['host']) : ''; diff --git a/app/Http/Middleware/VisitorDetector.php b/app/Http/Middleware/VisitorCounter.php similarity index 66% rename from app/Http/Middleware/VisitorDetector.php rename to app/Http/Middleware/VisitorCounter.php index c26959c..40ca5b5 100644 --- a/app/Http/Middleware/VisitorDetector.php +++ b/app/Http/Middleware/VisitorCounter.php @@ -4,12 +4,11 @@ namespace App\Http\Middleware; use App\Helpers\TVisitor; use App\Models\Visitor; -use Carbon\Carbon; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; -class VisitorDetector +class VisitorCounter { /** * Handle an incoming request. @@ -18,20 +17,26 @@ class VisitorDetector */ public function handle(Request $request, Closure $next): Response { - $visitor = Visitor::where('updated_at','>',date("Y-m-d H:i:s" ,time() - (60*60))) ->where('ip', $request->ip())->first(); if ($visitor === null) { $visitor = new Visitor(); $visitor->ip = $request->ip(); - $visitor->browser = TVisitor::DetectBrowserI(); - $visitor->os = TVisitor::DetectOSI(); + $visitor->browser = TVisitor::DetectBrowser(); + $visitor->os = TVisitor::DetectOS(); $visitor->version = TVisitor::BrowserVersion(); - $visitor->keywords = TVisitor::GetKeyword(); + $ref = TVisitor::GetKeyword(); + if ($ref !== null) { + $visitor->keywords = $ref['keyword']; + $visitor->engine = $ref['engine']; + } $visitor->is_mobile = TVisitor::IsMobile(); + $visitor->page = $request->route()->getName(); $visitor->save(); }else{ $visitor->increment('visit'); + $visitor->page = $request->route()->getName(); + $visitor->save(); } return $next($request); } diff --git a/app/Models/Visitor.php b/app/Models/Visitor.php index adb03f9..919390a 100644 --- a/app/Models/Visitor.php +++ b/app/Models/Visitor.php @@ -8,4 +8,75 @@ use Illuminate\Database\Eloquent\Model; class Visitor extends Model { use HasFactory; + + public static $engines = [ + 'google' => ['q', 'query'], + 'bing' => ['q'], + 'yahoo' => ['p'], + 'yandex' => ['text'], + 'baidu' => ['wd', 'word'], + 'duckduckgo' => ['q'], + 'ask' => ['q'], + 'aol' => ['q'], + 'naver' => ['query'], + 'ecosia' => ['q'], + ]; + + public static $browserList = ['Firefox' => '(Firefox)', + 'FirFox' => '(FireFox)', + 'Chrome' => '(Chrome)(?!.*Edge)', + 'Edge' => '(Edg|Edge)', + 'Opera' => '(OPR|Opera)', + 'Brave' => '(Brave)', + 'Safari' => '(Safari)(?!.*Chrome)', + 'Internet Explorer' => '(MSIE|Trident)', + 'DeepNet Explorer' => '(Deepnet)', + 'Flock' => '(Flock)', + 'Maxthon' => '(Maxthon)', + 'Avant Browser' => '(Avant)', + 'AOL' => '(AOL)', + 'Vivaldi' => '(Vivaldi)', + 'UC Browser' => '(UCBrowser)', + 'Yandex Browser' => '(YaBrowser)', + 'Samsung Internet' => '(SamsungBrowser)', + ]; + + public static $osList = [ + 'Linux' => '(Linux)', + 'Windows 11' => '(Windows NT 11.0)', // Added Windows 11 + 'Windows 10' => '(Windows NT 10.0)', + 'Mac OS X' => '(Mac OS X)', + 'Android' => '(Android)', + 'iOS' => '(iPhone)|(iPad)', + 'Windows 8.1' => '(Windows NT 6.3)', + 'Windows 8' => '(Windows NT 6.2)', + 'Windows 7' => '(Windows NT 6.1)', + 'Windows Vista' => '(Windows NT 6.0)', + 'Windows Server 2003/XP x64' => '(Windows NT 5.2)', + 'Windows XP' => '(Windows NT 5.1)', + 'Windows 2000' => '(Windows NT 5.0)', + 'Windows ME' => '(Win 9x 4.90)', + 'Windows 98' => '(Windows 98)', + 'Windows 95' => '(Windows 95)', + 'Windows CE' => '(Windows CE)', + 'Windows (iPhone/iPad)' => 'Windows (iPhone|iPad)', + 'Mac OS' => '(MacPPC)|(Mac_PowerPC)|(Macintosh)', + 'Ubuntu' => '(Ubuntu)', + 'Linux Mint' => '(Linux Mint)', + 'Debian' => '(Debian)', + 'Fedora' => '(Fedora)', + 'Red Hat' => '(Red Hat)', + 'SuSE' => '(SuSE)', + 'webOS' => '(webOS)|(hpwOS)', + 'BlackBerry' => '(BlackBerry)', + 'Symbian' => '(Symbian)', + 'FreeBSD' => '(FreeBSD)', + 'OpenBSD' => '(OpenBSD)', + 'NetBSD' => '(NetBSD)', + 'SunOS' => '(SunOS)', + 'OpenSolaris' => '(OpenSolaris)', + 'Chrome OS' => '(Chrome OS)|(CrOS)', + 'bot' => '(bot)' + ]; + } diff --git a/database/factories/VisitorFactory.php b/database/factories/VisitorFactory.php index 4842cfa..bd06c06 100644 --- a/database/factories/VisitorFactory.php +++ b/database/factories/VisitorFactory.php @@ -2,6 +2,8 @@ namespace Database\Factories; +use App\Helpers\TVisitor; +use App\Models\Visitor; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -17,18 +19,32 @@ class VisitorFactory extends Factory public function definition(): array { - $displays = ['1920x1080','1366x768','1920x1080','1366x768','1280x1024',null, null]; - $date = $this->faker->dateTimeBetween('-31 days', 'now'); + $displays = ['1920x1080', '1366x768', '1920x1080', '1366x768', '1280x1024', null, null]; + $displays_mobile = ['360x780', '430x932', '390x844', '375x667', '412x915', null, null]; + if (rand(0, 2) == 1) { + $date = $this->faker->dateTimeBetween('-30 days', 'now'); + } else { + $date = $this->faker->dateTimeBetween('-120 days', 'now'); + } + if (rand(1, 10) == 7) { + $keyword = $this->faker->word(); + $engine = array_keys(Visitor::$engines)[rand(0, count(Visitor::$engines) - 1)]; + } + $os = array_keys(Visitor::$osList)[rand(0, 6)]; + return [ // 'ip' => $this->faker->ipv4(), - 'visit' => rand(1,rand(2,12)), - 'browser' => rand(0,5), - 'os' => rand(0,14), - 'version' => rand(100,132), - 'display' => $displays[count($displays)-1], + 'visit' => rand(1, rand(2, 12)), + 'browser' => array_keys(Visitor::$browserList)[rand(0, 6)], + 'os' => $os, + 'version' => rand(100, 132), + 'display' => $os === 'iOS' || $os === 'Android' ? $displays_mobile[rand(0, count($displays_mobile) - 1)] : $displays[rand(0, count($displays) - 1)], 'updated_at' => $date, 'created_at' => $date, + 'keywords' => $keyword ?? null, + 'engine' => $engine ?? rand(0, 5) == 0 ? 'google' : null, + 'is_mobile' => $os === 'iOS' || $os === 'Android', ]; } } diff --git a/database/migrations/2024_07_16_042925_create_visitors_table.php b/database/migrations/2024_07_16_042925_create_visitors_table.php index f699d38..2e49f1b 100644 --- a/database/migrations/2024_07_16_042925_create_visitors_table.php +++ b/database/migrations/2024_07_16_042925_create_visitors_table.php @@ -15,12 +15,14 @@ return new class extends Migration $table->id(); $table->ipAddress('ip'); $table->unsignedInteger('visit')->default(1); - $table->unsignedInteger('browser')->nullable(); - $table->unsignedInteger('os')->nullable(); + $table->enum('browser',array_keys(\App\Models\Visitor::$browserList))->nullable(); + $table->enum('os',array_keys(\App\Models\Visitor::$osList))->nullable(); + $table->enum('engine',array_keys(\App\Models\Visitor::$engines))->nullable(); $table->string('version')->nullable(); $table->string('display')->nullable(); $table->string('keywords')->nullable(); $table->boolean('is_mobile')->default(false); + $table->string('page')->nullable(); $table->timestamps(); }); } diff --git a/database/seeders/VisitorSeeder.php b/database/seeders/VisitorSeeder.php index 8c2d995..be96a13 100644 --- a/database/seeders/VisitorSeeder.php +++ b/database/seeders/VisitorSeeder.php @@ -14,6 +14,6 @@ class VisitorSeeder extends Seeder public function run(): void { // - Visitor::factory()->count(110)->create(); + Visitor::factory()->count(1250)->create(); } } diff --git a/routes/web.php b/routes/web.php index 1f30153..479193a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -5,7 +5,7 @@ use Illuminate\Support\Facades\Route; Route::get('/', function () { return view('welcome'); -})->name('welcome')->middleware(\App\Http\Middleware\VisitorDetector::class); +})->name('welcome')->middleware(\App\Http\Middleware\VisitorCounter::class); Auth::routes(['register' => false]); @@ -340,9 +340,7 @@ Route::prefix(config('app.panel.prefix'))->name('admin.')->group( Route::get('test',function (){ // return \Resources\Views\Segments\PreloaderCircle::onAdd(); - $p = \App\Models\Product::where('id',31)->first(); - - return $p->fullMeta(); + return \App\Helpers\TVisitor::GetKeyword(); });