Initial commit. First version added.

This commit is contained in:
Alexey Skobkin 2017-09-05 04:28:08 +03:00
commit 09929c7b3a
7 changed files with 357 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/.idea
/vendor

21
composer.json Normal file
View file

@ -0,0 +1,21 @@
{
"name": "skobkin/ip-detect",
"license": "MIT",
"type": "project",
"description": "Minimalistic IP remote IP detector application",
"homepage": "http://ip.skobk.in/",
"authors": [
{
"name": "Alexey Skobkin",
"email": "skobkin-ru@ya.ru",
"homepage": "https://skobk.in/"
}
],
"autoload": {
"psr-4": { "App\\": "src/" }
},
"require": {
"symfony/http-foundation": "^3.3",
"slim/php-view": "^2.2"
}
}

229
composer.lock generated Normal file
View file

@ -0,0 +1,229 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "eff3b1001b5ae7db5011252de36831ba",
"packages": [
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "slim/php-view",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/PHP-View.git",
"reference": "122ed121a8d9cf91a94020814d2a3ee6c836754f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/PHP-View/zipball/122ed121a8d9cf91a94020814d2a3ee6c836754f",
"reference": "122ed121a8d9cf91a94020814d2a3ee6c836754f",
"shasum": ""
},
"require": {
"psr/http-message": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8",
"slim/slim": "^3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Slim\\Views\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Glenn Eggleton",
"email": "geggleto@gmail.com"
}
],
"description": "Render PHP view scripts into a PSR-7 Response object.",
"keywords": [
"framework",
"php",
"phtml",
"renderer",
"slim",
"template",
"view"
],
"time": "2016-10-11T07:43:08+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v3.3.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "14bacad23a4f075bfd3fd456755236cb261320e3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/14bacad23a4f075bfd3fd456755236cb261320e3",
"reference": "14bacad23a4f075bfd3fd456755236cb261320e3",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8",
"symfony/polyfill-mbstring": "~1.1"
},
"require-dev": {
"symfony/expression-language": "~2.8|~3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2017-08-10T07:07:06+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7c8fae0ac1d216eb54349e6a8baa57d515fe8803",
"reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"time": "2017-06-14T15:44:48+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}

11
public/index.php Normal file
View file

@ -0,0 +1,11 @@
<?php
namespace App;
use \Symfony\Component\HttpFoundation\Request;
$loader = require __DIR__.'/../vendor/autoload.php';
$request = Request::createFromGlobals();
AppKernel::handle($request);

44
src/AppKernel.php Normal file
View file

@ -0,0 +1,44 @@
<?php
namespace App;
use App\Controller\DetectorController;
use Symfony\Component\HttpFoundation\{Request, Response};
use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
final class AppKernel
{
public const KERNEL_ROOT = __DIR__;
public const PROJECT_ROOT = __DIR__.'/..';
public static function handle(Request $request): void
{
$response = new Response();
try {
$response = static::handleRaw($request);
} catch (RequestExceptionInterface $e) {
$response->setStatusCode($e->getCode());
$response->setContent($e->getMessage());
} catch (\Throwable $e) {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
$response->setContent('Server error');
}
$response->send();
}
public static function handleRaw(Request $request): Response
{
// It's a kind of routing you know...
if ('/json' === $request->getPathInfo()) {
$format = DetectorController::FORMAT_JSON;
} elseif ('/' === $request->getPathInfo()) {
$format = DetectorController::FORMAT_HTML;
} else {
return new Response('Resource not found', Response::HTTP_NOT_FOUND);
}
return DetectorController::detect($request, $format);
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace App\Controller;
use App\AppKernel;
use Slim\Views\PhpRenderer;
use Symfony\Component\HttpFoundation\{JsonResponse, Request, Response};
final class DetectorController
{
public const FORMAT_JSON = 'json';
public const FORMAT_HTML = 'html';
private const TEMPLATES_PATH = AppKernel::PROJECT_ROOT.'/templates';
public static function detect(Request $request, string $format = 'html'): Response
{
$clientData = [
'ip_address' => $request->getClientIp(),
'locale' => $request->getLocale(),
'preferred_language' => $request->getPreferredLanguage(),
];
if (static::FORMAT_JSON === $format) {
return new JsonResponse($clientData);
}
$templater = new PhpRenderer(static::TEMPLATES_PATH);
$templater->setAttributes($clientData);
return new Response($templater->fetch('/client_data.php', $clientData));
}
}

17
templates/client_data.php Normal file
View file

@ -0,0 +1,17 @@
<?php /** @var \Slim\Views\PhpRenderer $this */ ?>
<!DOCTYPE html>
<html>
<head>
<title>IP address</title>
</head>
<body>
<h1><?php echo htmlspecialchars($this->getAttribute('ip_address')); ?></h1>
<pre>
locale: <?php echo htmlspecialchars($this->getAttribute('locale')); ?>
preferred language: <?php echo htmlspecialchars($this->getAttribute('preferred_language')); ?>
</pre>
</body>
</html>