Sync
This commit is contained in:
@@ -65,7 +65,6 @@ VITE_PUSHER_PORT="${PUSHER_PORT}"
|
|||||||
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
||||||
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
|
|
||||||
MAXMIND_LICENSE_KEY=xxxxxx_yyyyyyyyyyyyyyyyzzzzzzzzzzz
|
|
||||||
LOCATION_TESTING=false
|
LOCATION_TESTING=false
|
||||||
|
|
||||||
DEV_DEFAULT_LOCATION=MY
|
DEV_DEFAULT_LOCATION=MY
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ class Kernel extends HttpKernel
|
|||||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
\App\Http\Middleware\StoreGeoSession::class,
|
|
||||||
\Spatie\GoogleTagManager\GoogleTagManagerMiddleware::class,
|
\Spatie\GoogleTagManager\GoogleTagManagerMiddleware::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Middleware;
|
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use Galahad\TimezoneMapper\Facades\TimezoneMapper;
|
|
||||||
use Stevebauman\Location\Facades\Location;
|
|
||||||
|
|
||||||
class StoreGeoSession
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Handle an incoming request.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function handle($request, Closure $next)
|
|
||||||
{
|
|
||||||
$needs_update = false;
|
|
||||||
|
|
||||||
$ip = get_current_ip();
|
|
||||||
$encoded_ip = base64_encode($ip);
|
|
||||||
|
|
||||||
if (! $request->session()->has('geokey')) {
|
|
||||||
if ($request->session()->get('geokey') != $encoded_ip) {
|
|
||||||
$request->session()->put('geokey', $encoded_ip);
|
|
||||||
$needs_update = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$request->session()->put('geokey', $encoded_ip);
|
|
||||||
$needs_update = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $request->session()->has('timezone')) {
|
|
||||||
$needs_update = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($needs_update) {
|
|
||||||
|
|
||||||
if ($payload = Location::get($ip)) {
|
|
||||||
$request->session()->put('geodata', base64_encode(json_encode($payload)));
|
|
||||||
$isocode = $payload->isoCode;
|
|
||||||
} else {
|
|
||||||
$isocode = '*';
|
|
||||||
}
|
|
||||||
|
|
||||||
$request->session()->put('country', $isocode);
|
|
||||||
|
|
||||||
if (isset($payload->latitude) && isset($payload->longitude)) {
|
|
||||||
$request->session()->put('timezone', TimezoneMapper::mapCoordinates($payload->latitude, $payload->longitude));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $next($request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
224
app/ThirdParty/SteveBaumanLocation/MaxMindDriver.php
vendored
224
app/ThirdParty/SteveBaumanLocation/MaxMindDriver.php
vendored
@@ -1,224 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\ThirdParty\SteveBaumanLocation;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use GeoIp2\Database\Reader;
|
|
||||||
use GeoIp2\Model\City;
|
|
||||||
use GeoIp2\Model\Country;
|
|
||||||
use GeoIp2\WebService\Client;
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Illuminate\Support\Fluent;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use PharData;
|
|
||||||
use PharFileInfo;
|
|
||||||
use Stevebauman\Location\Drivers\Driver;
|
|
||||||
use Stevebauman\Location\Drivers\Updatable;
|
|
||||||
use Stevebauman\Location\Position;
|
|
||||||
use Stevebauman\Location\Request;
|
|
||||||
|
|
||||||
class MaxMindDriver extends Driver implements Updatable
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Update the MaxMind database.
|
|
||||||
*/
|
|
||||||
public function update(Command $command): void
|
|
||||||
{
|
|
||||||
$storage = Storage::build([
|
|
||||||
'driver' => 'local',
|
|
||||||
'root' => sys_get_temp_dir(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$storage->put(
|
|
||||||
$tar = 'maxmind.tar.gz',
|
|
||||||
fopen($this->getDatabaseUrl(), 'r')
|
|
||||||
);
|
|
||||||
|
|
||||||
$file = $this->discoverDatabaseFile(
|
|
||||||
$archive = new PharData($storage->path($tar))
|
|
||||||
);
|
|
||||||
|
|
||||||
$relativePath = implode('/', [
|
|
||||||
Str::afterLast($file->getPath(), DIRECTORY_SEPARATOR),
|
|
||||||
$file->getFilename(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$archive->extractTo($storage->path('/'), $relativePath, true);
|
|
||||||
|
|
||||||
@mkdir(
|
|
||||||
Str::beforeLast($this->getDatabasePath(), DIRECTORY_SEPARATOR)
|
|
||||||
);
|
|
||||||
|
|
||||||
file_put_contents(
|
|
||||||
$this->getDatabasePath(),
|
|
||||||
fopen($storage->path($relativePath), 'r')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to discover the database file inside the archive.
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
protected function discoverDatabaseFile(PharData $archive): PharFileInfo
|
|
||||||
{
|
|
||||||
/** @var \FilesystemIterator $file */
|
|
||||||
foreach ($archive as $file) {
|
|
||||||
if ($file->isDir()) {
|
|
||||||
return $this->discoverDatabaseFile(
|
|
||||||
new PharData($file->getPathName())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pathinfo($file, PATHINFO_EXTENSION) === 'mmdb') {
|
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception('Unable to locate database file inside of MaxMind archive.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected function hydrate(Position $position, Fluent $location): Position
|
|
||||||
{
|
|
||||||
$position->countryName = $location->country;
|
|
||||||
$position->countryCode = $location->country_code;
|
|
||||||
$position->isoCode = $location->country_code;
|
|
||||||
$position->regionCode = $location->regionCode;
|
|
||||||
$position->regionName = $location->regionName;
|
|
||||||
$position->cityName = $location->city;
|
|
||||||
$position->postalCode = $location->postal;
|
|
||||||
$position->metroCode = $location->metro_code;
|
|
||||||
$position->timezone = $location->time_zone;
|
|
||||||
$position->latitude = $location->latitude;
|
|
||||||
$position->longitude = $location->longitude;
|
|
||||||
|
|
||||||
return $position;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected function process(Request $request): Fluent|false
|
|
||||||
{
|
|
||||||
return rescue(function () use ($request) {
|
|
||||||
$record = $this->fetchLocation($request->getIp());
|
|
||||||
|
|
||||||
if ($record instanceof City) {
|
|
||||||
return new Fluent([
|
|
||||||
'country' => $record->country->name,
|
|
||||||
'country_code' => $record->country->isoCode,
|
|
||||||
'city' => $record->city->name,
|
|
||||||
'regionCode' => $record->mostSpecificSubdivision->isoCode,
|
|
||||||
'regionName' => $record->mostSpecificSubdivision->name,
|
|
||||||
'postal' => $record->postal->code,
|
|
||||||
'timezone' => $record->location->timeZone,
|
|
||||||
'latitude' => (string) $record->location->latitude,
|
|
||||||
'longitude' => (string) $record->location->longitude,
|
|
||||||
'metro_code' => (string) $record->location->metroCode,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Fluent([
|
|
||||||
'country' => $record->country->name,
|
|
||||||
'country_code' => $record->country->isoCode,
|
|
||||||
]);
|
|
||||||
}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to fetch the location model from Maxmind.
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
protected function fetchLocation(string $ip): City|Country
|
|
||||||
{
|
|
||||||
$maxmind = $this->isWebServiceEnabled()
|
|
||||||
? $this->newClient($this->getUserId(), $this->getLicenseKey(), $this->getOptions())
|
|
||||||
: $this->newReader($this->getDatabasePath());
|
|
||||||
|
|
||||||
if ($this->isWebServiceEnabled() || $this->getLocationType() === 'city') {
|
|
||||||
return $maxmind->city($ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $maxmind->country($ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a new MaxMind web service client.
|
|
||||||
*/
|
|
||||||
protected function newClient(string $userId, string $licenseKey, array $options = []): Client
|
|
||||||
{
|
|
||||||
return new Client($userId, $licenseKey, $options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a new MaxMind reader client.
|
|
||||||
*/
|
|
||||||
protected function newReader(string $path): Reader
|
|
||||||
{
|
|
||||||
return new Reader($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true / false if the MaxMind web service is enabled.
|
|
||||||
*/
|
|
||||||
protected function isWebServiceEnabled(): bool
|
|
||||||
{
|
|
||||||
return (bool) config('location.maxmind.web.enabled', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the configured MaxMind web user ID.
|
|
||||||
*/
|
|
||||||
protected function getUserId(): string
|
|
||||||
{
|
|
||||||
return config('location.maxmind.web.user_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the configured MaxMind web license key.
|
|
||||||
*/
|
|
||||||
protected function getLicenseKey(): string
|
|
||||||
{
|
|
||||||
return config('location.maxmind.web.license_key');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the configured MaxMind web option array.
|
|
||||||
*/
|
|
||||||
protected function getOptions(): array
|
|
||||||
{
|
|
||||||
return config('location.maxmind.web.options', []);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the MaxMind database file path.
|
|
||||||
*/
|
|
||||||
protected function getDatabasePath(): string
|
|
||||||
{
|
|
||||||
return config('location.maxmind.local.path', database_path('maxmind/GeoLite2-City.mmdb'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the database URL to download.
|
|
||||||
*/
|
|
||||||
protected function getDatabaseUrl(): string
|
|
||||||
{
|
|
||||||
return config(
|
|
||||||
'location.maxmind.local.url',
|
|
||||||
sprintf('https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=%s&suffix=tar.gz', $this->getLicenseKey()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the MaxMind location type.
|
|
||||||
*/
|
|
||||||
protected function getLocationType(): string
|
|
||||||
{
|
|
||||||
return config('location.maxmind.local.type', 'city');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -38,7 +38,6 @@
|
|||||||
"spatie/laravel-googletagmanager": "^2.6",
|
"spatie/laravel-googletagmanager": "^2.6",
|
||||||
"spatie/laravel-responsecache": "^7.4",
|
"spatie/laravel-responsecache": "^7.4",
|
||||||
"spatie/laravel-sitemap": "^6.3",
|
"spatie/laravel-sitemap": "^6.3",
|
||||||
"stevebauman/location": "^7.0",
|
|
||||||
"symfony/dom-crawler": "^6.3",
|
"symfony/dom-crawler": "^6.3",
|
||||||
"thiagoalessio/tesseract_ocr": "^2.12",
|
"thiagoalessio/tesseract_ocr": "^2.12",
|
||||||
"tightenco/ziggy": "^1.6",
|
"tightenco/ziggy": "^1.6",
|
||||||
|
|||||||
1135
composer.lock
generated
1135
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -160,7 +160,6 @@
|
|||||||
* Package Service Providers...
|
* Package Service Providers...
|
||||||
*/
|
*/
|
||||||
Barryvdh\Debugbar\ServiceProvider::class,
|
Barryvdh\Debugbar\ServiceProvider::class,
|
||||||
Stevebauman\Location\LocationServiceProvider::class,
|
|
||||||
Artesaos\SEOTools\Providers\SEOToolsServiceProvider::class,
|
Artesaos\SEOTools\Providers\SEOToolsServiceProvider::class,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
return [
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Driver
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The default driver you would like to use for location retrieval.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'driver' => \App\ThirdParty\SteveBaumanLocation\MaxMindDriver::class,
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Driver Fallbacks
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The drivers you want to use to retrieve the user's location
|
|
||||||
| if the above selected driver is unavailable.
|
|
||||||
|
|
|
||||||
| These will be called upon in order (first to last).
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'fallbacks' => [
|
|
||||||
\App\ThirdParty\SteveBaumanLocation\MaxMindDriver::class,
|
|
||||||
],
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Position
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| Here you may configure the position instance that is created
|
|
||||||
| and returned from the above drivers. The instance you
|
|
||||||
| create must extend the built-in Position class.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'position' => Stevebauman\Location\Position::class,
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Localhost Testing
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| If your running your website locally and want to test different
|
|
||||||
| IP addresses to see location detection, set 'enabled' to true.
|
|
||||||
|
|
|
||||||
| The testing IP address is a Google host in the United-States.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'testing' => [
|
|
||||||
'ip' => env('DEV_DEFAULT_IP'),
|
|
||||||
'enabled' => env('LOCATION_TESTING', true),
|
|
||||||
],
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| MaxMind Configuration
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| If web service is enabled, you must fill in your user ID and license key.
|
|
||||||
|
|
|
||||||
| If web service is disabled, it will try and retrieve the user's location
|
|
||||||
| from the MaxMind database file located in the local path below.
|
|
||||||
|
|
|
||||||
| The MaxMind database file can be either City (default) or Country (smaller).
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'maxmind' => [
|
|
||||||
'web' => [
|
|
||||||
'enabled' => false,
|
|
||||||
'user_id' => env('MAXMIND_USER_ID'),
|
|
||||||
'license_key' => env('MAXMIND_LICENSE_KEY'),
|
|
||||||
'options' => ['host' => 'geoip.maxmind.com'],
|
|
||||||
],
|
|
||||||
|
|
||||||
'local' => [
|
|
||||||
'type' => 'city',
|
|
||||||
'path' => database_path('maxmind/GeoLite2-City.mmdb'),
|
|
||||||
'url' => sprintf('https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=%s&suffix=tar.gz', env('MAXMIND_LICENSE_KEY')),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
|
|
||||||
'ip_api' => [
|
|
||||||
'token' => env('IP_API_TOKEN'),
|
|
||||||
],
|
|
||||||
|
|
||||||
'ipinfo' => [
|
|
||||||
'token' => env('IPINFO_TOKEN'),
|
|
||||||
],
|
|
||||||
|
|
||||||
'ipdata' => [
|
|
||||||
'token' => env('IPDATA_TOKEN'),
|
|
||||||
],
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Kloudend ~ ipapi.co Configuration
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The configuration for the Kloudend driver.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'kloudend' => [
|
|
||||||
|
|
||||||
'token' => env('KLOUDEND_TOKEN'),
|
|
||||||
|
|
||||||
],
|
|
||||||
|
|
||||||
];
|
|
||||||
1
database/maxmind/.gitignore
vendored
1
database/maxmind/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
*.mmdb*
|
|
||||||
Reference in New Issue
Block a user