Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

homework-5 #1523

Open
wants to merge 3 commits into
base: RYessaliyev/master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
UID=3000
NGINX_PHP_USER=nginxphpuser
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.env
data
vendor
2 changes: 2 additions & 0 deletions app/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
LOG_PATH=../logs/app.log
BASE_EMAIL_VALIDATOR=EMAIL_VALIDATOR
1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
5 changes: 5 additions & 0 deletions app/bootstrap/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php
require_once '../vendor/autoload.php';

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/..');
$dotenv->load();
13 changes: 13 additions & 0 deletions app/public/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

use App\App;
use App\Response\Response;

require_once '../bootstrap/bootstrap.php';

try {
$app = new App();
$app->run();
} catch (\Throwable $e) {
Response::send($e->getCode(), $e->getMessage());
}
28 changes: 28 additions & 0 deletions app/src/App.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App;

use App\EmailValidator\EmailValidator;
use App\EmailValidator\ValidatorFactory;
use App\Exceptions\AppException;
use App\Request\Request;
use App\Response\Response;

class App
{
/**
* @throws AppException
*/
public function run()
{
$data = (new Request())->getData();

if (empty($data['emails']) and !is_array($data['emails'])) {
throw new AppException('Не передан emails', Response::BAD_REQUEST);
}

$validator = ValidatorFactory::factory();
$validator->setEmails($data['emails']);
$validator->validate();
}
}
32 changes: 32 additions & 0 deletions app/src/EmailValidator/AbstractValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\EmailValidator;

use App\Response\Response;

abstract class AbstractValidator
{
private array $emails;

public function validate()
{
$result = [];

foreach($this->emails as $email) {
if (!$this->isValidEmail($email,true)){
$result[] = ["email" => $email, 'status' => 'invalid'];
} else {
$result[] = ["email" => $email, 'status' => 'valid'];
}
}

Response::send(Response::OK, "email-ы проверены", $result);
}

public function setEmails(array $emails): void
{
$this->emails = $emails;
}

abstract protected function isValidEmail(string $email, $extended = false);
}
37 changes: 37 additions & 0 deletions app/src/EmailValidator/EmailValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace App\EmailValidator;

use App\AppException;
use App\Request\Request;
use App\Response\Response;

class EmailValidator extends AbstractValidator {

public const VALIDATOR_NAME = 'EMAIL_VALIDATOR';

protected function isValidEmail(string $email, $extended = false)
{
if (empty($email)) {
return false;
}

if (!preg_match('/^([a-z0-9_\'&\\.\\-\\+])+\\@(([a-z0-9\\-])+\\.)+([a-z0-9]{2,10})+$/i', $email)) {
return false;
}

$domain = substr($email, strrpos($email, '@') + 1);
$mxhosts = [];

$checkDomain = getmxrr($domain, $mxhosts);

if (!$checkDomain || empty($mxhosts)) {
$dns = dns_get_record($domain, DNS_A);
if (empty($dns)) {
return false;
}
}

return true;
}
}
24 changes: 24 additions & 0 deletions app/src/EmailValidator/ValidatorFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php


namespace App\EmailValidator;


use App\Exceptions\AppException;

class ValidatorFactory
{
/**
* @return EmailValidator
* @throws AppException
*/
public static function factory()
{
switch ($_ENV['BASE_EMAIL_VALIDATOR']) {
case EmailValidator::VALIDATOR_NAME:
return new EmailValidator();
default:
throw new AppException('Валидатор не найден');
}
}
}
16 changes: 16 additions & 0 deletions app/src/Exceptions/AppException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Exceptions;

use App\Logger\AppLogger;
use Exception;
use Monolog\Logger;

class AppException extends Exception
{
public function __construct($message = "", $code = 0, \Throwable $previous = null)
{
AppLogger::addLog(Logger::ERROR, $message);
parent::__construct($message, $code, $previous);
}
}
16 changes: 16 additions & 0 deletions app/src/Logger/AppLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Logger;

use Monolog\Handler\StreamHandler;
use Monolog\Logger;

class AppLogger
{
public static function addLog(int $level, string $message, $context = []): void
{
$log = new Logger('app');
$log->pushHandler(new StreamHandler($_ENV['LOG_PATH']));
$log->addRecord($level, $message, $context);
}
}
31 changes: 31 additions & 0 deletions app/src/Request/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Request;

use App\Exceptions\AppException;
use App\Exceptions\RequestException;

class Request
{
private array $data;

/**
* Request constructor.
* @throws AppException
*/
public function __construct()
{
$json = file_get_contents('php://input');

if (json_last_error() !== JSON_ERROR_NONE) {
throw new AppException(json_last_error_msg(), 400);
}

$this->data = json_decode($json, true);
}

public function getData(): array
{
return $this->data;
}
}
33 changes: 33 additions & 0 deletions app/src/Response/Response.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Response;

class Response
{
public const OK = 200;
public const BAD_REQUEST = 400;
public const UNPROCESSABLE_ENTITY = 422;
public const SERVER_ERROR = 500;

public static function send($code = 200, $message = '', $data = [])
{
$code = $code === 0 ? self::SERVER_ERROR : $code;

http_response_code($code);
header('Content-Type: application/json');
$status = array(
self::OK => '200 OK',
self::BAD_REQUEST => '400 Bad Request',
self::UNPROCESSABLE_ENTITY => 'Unprocessable Entity',
self::SERVER_ERROR => '500 Internal Server Error'
);

header('Status: '.$status[$code]);

$result['status'] = $code < 300 ? "success" : "error";
$result['message'] = $message;
$result['data'] = $data;

echo json_encode($result);
}
}
55 changes: 55 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
version: '3.8'

services:
nginx:
container_name: nginx
build:
context: ./docker/nginx
args:
UID: $UID
NGINX_PHP_USER: $NGINX_PHP_USER
volumes:
- ./app:/var/www/html
- ./docker/sock-1:/sock-1
- ./docker/sock-2:/sock-2
- ./docker/sock-3:/sock-3
ports:
- "8787:80"
depends_on:
- php-fpm-1
- php-fpm-2
- php-fpm-3

php-fpm-1:
container_name: php-fpm-1
build:
context: ./docker/php-fpm-1
args:
UID: $UID
NGINX_PHP_USER: $NGINX_PHP_USER
volumes:
- ./app:/var/www/html
- ./docker/sock-1:/sock-1

php-fpm-2:
container_name: php-fpm-2
build:
context: ./docker/php-fpm-2
args:
UID: $UID
NGINX_PHP_USER: $NGINX_PHP_USER
volumes:
- ./app:/var/www/html
- ./docker/sock-2:/sock-2

php-fpm-3:
container_name: php-fpm-3
build:
context: ./docker/php-fpm-3
args:
UID: $UID
NGINX_PHP_USER: $NGINX_PHP_USER
volumes:
- ./app:/var/www/html
- ./docker/sock-3:/sock-3

11 changes: 11 additions & 0 deletions docker/nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM nginx
WORKDIR /var/www/html

ARG UID
ARG NGINX_PHP_USER

COPY nginx.conf /etc/nginx/nginx.conf
COPY mysite.conf /etc/nginx/conf.d/default.conf
RUN addgroup --gid $UID --system $NGINX_PHP_USER \
&& adduser --uid $UID --system --disabled-login --disabled-password --gid $UID $NGINX_PHP_USER \
&& sed -i -r "s/%REPLACE_USERNAME%/$NGINX_PHP_USER/g" /etc/nginx/nginx.conf
27 changes: 27 additions & 0 deletions docker/nginx/mysite.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
upstream servers {
server unix:/sock-1/docker.sock;
server unix:/sock-2/docker.sock;
server unix:/sock-3/docker.sock;
}

server {
listen 80;
listen [::]:80;

index index.php;
root /var/www/html/public;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
fastcgi_pass servers;
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
}
Loading