optimized visitor model, migration, middleware, seeder

pull/44/head
A1Gard 2 months ago
parent 8bef2c82b4
commit 3166710510

@ -2,6 +2,8 @@
namespace App\Helpers;
use App\Models\Visitor;
/**
* @package Helpers
* @author A1Gard <a1gard@4xmen.ir>
@ -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']) : '';

@ -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);
}

@ -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)'
];
}

@ -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',
];
}
}

@ -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();
});
}

@ -14,6 +14,6 @@ class VisitorSeeder extends Seeder
public function run(): void
{
//
Visitor::factory()->count(110)->create();
Visitor::factory()->count(1250)->create();
}
}

@ -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();
});

Loading…
Cancel
Save