diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..91a80adb9 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +UID=3000 +NGINX_PHP_USER=nginxphpuser \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b21c49049 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +data +vendor \ No newline at end of file diff --git a/app/.env.example b/app/.env.example new file mode 100644 index 000000000..f6b5403d4 --- /dev/null +++ b/app/.env.example @@ -0,0 +1,2 @@ +LOG_PATH=../logs/app.log +BASE_EMAIL_VALIDATOR=EMAIL_VALIDATOR \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 000000000..2eea525d8 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/app/bootstrap/bootstrap.php b/app/bootstrap/bootstrap.php new file mode 100644 index 000000000..47d4467fe --- /dev/null +++ b/app/bootstrap/bootstrap.php @@ -0,0 +1,5 @@ +load(); \ No newline at end of file diff --git a/app/public/index.php b/app/public/index.php new file mode 100644 index 000000000..40f433258 --- /dev/null +++ b/app/public/index.php @@ -0,0 +1,13 @@ +run(); +} catch (\Throwable $e) { + Response::send($e->getCode(), $e->getMessage()); +} diff --git a/app/src/App.php b/app/src/App.php new file mode 100644 index 000000000..4483b0d0f --- /dev/null +++ b/app/src/App.php @@ -0,0 +1,28 @@ +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(); + } +} \ No newline at end of file diff --git a/app/src/EmailValidator/AbstractValidator.php b/app/src/EmailValidator/AbstractValidator.php new file mode 100644 index 000000000..437792888 --- /dev/null +++ b/app/src/EmailValidator/AbstractValidator.php @@ -0,0 +1,32 @@ +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); +} \ No newline at end of file diff --git a/app/src/EmailValidator/EmailValidator.php b/app/src/EmailValidator/EmailValidator.php new file mode 100644 index 000000000..d40a4d88f --- /dev/null +++ b/app/src/EmailValidator/EmailValidator.php @@ -0,0 +1,37 @@ +pushHandler(new StreamHandler($_ENV['LOG_PATH'])); + $log->addRecord($level, $message, $context); + } +} \ No newline at end of file diff --git a/app/src/Request/Request.php b/app/src/Request/Request.php new file mode 100644 index 000000000..7eeb85766 --- /dev/null +++ b/app/src/Request/Request.php @@ -0,0 +1,31 @@ +data = json_decode($json, true); + } + + public function getData(): array + { + return $this->data; + } +} \ No newline at end of file diff --git a/app/src/Response/Response.php b/app/src/Response/Response.php new file mode 100644 index 000000000..9ebfb9f4d --- /dev/null +++ b/app/src/Response/Response.php @@ -0,0 +1,33 @@ + '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); + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..2b477b8e3 --- /dev/null +++ b/docker-compose.yml @@ -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 + diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile new file mode 100644 index 000000000..fe1f2670b --- /dev/null +++ b/docker/nginx/Dockerfile @@ -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 \ No newline at end of file diff --git a/docker/nginx/mysite.conf b/docker/nginx/mysite.conf new file mode 100644 index 000000000..1fa7b2bee --- /dev/null +++ b/docker/nginx/mysite.conf @@ -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; +} \ No newline at end of file diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf new file mode 100644 index 000000000..29b8d8a6c --- /dev/null +++ b/docker/nginx/nginx.conf @@ -0,0 +1,40 @@ +user %REPLACE_USERNAME%; +worker_processes auto; + +pid /var/run/nginx.pid; +error_log /var/log/nginx/error.log crit; + +events { + use epoll; + worker_connections 4096; + multi_accept on; +} +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + access_log off; + + keepalive_timeout 30; + keepalive_requests 100; + + client_max_body_size 1m; + client_body_timeout 10; + reset_timedout_connection on; + send_timeout 2; + sendfile on; + tcp_nodelay on; + tcp_nopush on; + + gzip on; + gzip_disable "msie6"; + gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; + + open_file_cache max=200000 inactive=20s; + open_file_cache_valid 30s; + open_file_cache_min_uses 2; + open_file_cache_errors on; + + include /etc/nginx/conf.d/*.conf; + +} \ No newline at end of file diff --git a/docker/php-fpm-1/Dockerfile b/docker/php-fpm-1/Dockerfile new file mode 100644 index 000000000..1bab9d5f4 --- /dev/null +++ b/docker/php-fpm-1/Dockerfile @@ -0,0 +1,50 @@ +FROM php:7.4-fpm + +ARG UID +ARG NGINX_PHP_USER +ENV DOCKER_PATH=/usr/local/etc/php-fpm.d/zz-docker.conf + +COPY zz-docker.conf $DOCKER_PATH + + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \ + && apt-get update \ + && apt-get install -y \ + git \ + curl \ + wget \ + grep \ + zip \ + unzip \ + libmemcached-dev \ + zlib1g-dev \ + libzip-dev \ + libcurl4-openssl-dev \ + libbrotli-dev \ + libevent-dev \ + libicu-dev \ + libidn11-dev \ + libidn2-0-dev \ + libssl-dev \ + libpq-dev \ + libonig-dev \ + librabbitmq-dev \ + nano \ + && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ + && pecl install memcached \ + && docker-php-ext-enable memcached \ + && docker-php-ext-install pdo pdo_pgsql pgsql \ + && pecl install xdebug-2.9.8 && docker-php-ext-enable xdebug \ + && pecl install -o redis && docker-php-ext-enable redis \ + && docker-php-ext-install zip sockets bcmath mbstring \ + && pecl install amqp && docker-php-ext-enable amqp \ + && 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" $DOCKER_PATH \ + && rm -rf /tmp/pear + +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +WORKDIR /var/www/html + +CMD ["php-fpm"] \ No newline at end of file diff --git a/docker/php-fpm-1/zz-docker.conf b/docker/php-fpm-1/zz-docker.conf new file mode 100644 index 000000000..94e9183cc --- /dev/null +++ b/docker/php-fpm-1/zz-docker.conf @@ -0,0 +1,8 @@ +[global] +daemonize = no + +[www] +listen = /sock-1/docker.sock +listen.owner = %REPLACE_USERNAME% +listen.group = %REPLACE_USERNAME% +listen.mode = 0660 \ No newline at end of file diff --git a/docker/php-fpm-2/Dockerfile b/docker/php-fpm-2/Dockerfile new file mode 100644 index 000000000..1bab9d5f4 --- /dev/null +++ b/docker/php-fpm-2/Dockerfile @@ -0,0 +1,50 @@ +FROM php:7.4-fpm + +ARG UID +ARG NGINX_PHP_USER +ENV DOCKER_PATH=/usr/local/etc/php-fpm.d/zz-docker.conf + +COPY zz-docker.conf $DOCKER_PATH + + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \ + && apt-get update \ + && apt-get install -y \ + git \ + curl \ + wget \ + grep \ + zip \ + unzip \ + libmemcached-dev \ + zlib1g-dev \ + libzip-dev \ + libcurl4-openssl-dev \ + libbrotli-dev \ + libevent-dev \ + libicu-dev \ + libidn11-dev \ + libidn2-0-dev \ + libssl-dev \ + libpq-dev \ + libonig-dev \ + librabbitmq-dev \ + nano \ + && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ + && pecl install memcached \ + && docker-php-ext-enable memcached \ + && docker-php-ext-install pdo pdo_pgsql pgsql \ + && pecl install xdebug-2.9.8 && docker-php-ext-enable xdebug \ + && pecl install -o redis && docker-php-ext-enable redis \ + && docker-php-ext-install zip sockets bcmath mbstring \ + && pecl install amqp && docker-php-ext-enable amqp \ + && 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" $DOCKER_PATH \ + && rm -rf /tmp/pear + +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +WORKDIR /var/www/html + +CMD ["php-fpm"] \ No newline at end of file diff --git a/docker/php-fpm-2/zz-docker.conf b/docker/php-fpm-2/zz-docker.conf new file mode 100644 index 000000000..26dca1ba7 --- /dev/null +++ b/docker/php-fpm-2/zz-docker.conf @@ -0,0 +1,8 @@ +[global] +daemonize = no + +[www] +listen = /sock-2/docker.sock +listen.owner = %REPLACE_USERNAME% +listen.group = %REPLACE_USERNAME% +listen.mode = 0660 \ No newline at end of file diff --git a/docker/php-fpm-3/Dockerfile b/docker/php-fpm-3/Dockerfile new file mode 100644 index 000000000..1bab9d5f4 --- /dev/null +++ b/docker/php-fpm-3/Dockerfile @@ -0,0 +1,50 @@ +FROM php:7.4-fpm + +ARG UID +ARG NGINX_PHP_USER +ENV DOCKER_PATH=/usr/local/etc/php-fpm.d/zz-docker.conf + +COPY zz-docker.conf $DOCKER_PATH + + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \ + && apt-get update \ + && apt-get install -y \ + git \ + curl \ + wget \ + grep \ + zip \ + unzip \ + libmemcached-dev \ + zlib1g-dev \ + libzip-dev \ + libcurl4-openssl-dev \ + libbrotli-dev \ + libevent-dev \ + libicu-dev \ + libidn11-dev \ + libidn2-0-dev \ + libssl-dev \ + libpq-dev \ + libonig-dev \ + librabbitmq-dev \ + nano \ + && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ + && pecl install memcached \ + && docker-php-ext-enable memcached \ + && docker-php-ext-install pdo pdo_pgsql pgsql \ + && pecl install xdebug-2.9.8 && docker-php-ext-enable xdebug \ + && pecl install -o redis && docker-php-ext-enable redis \ + && docker-php-ext-install zip sockets bcmath mbstring \ + && pecl install amqp && docker-php-ext-enable amqp \ + && 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" $DOCKER_PATH \ + && rm -rf /tmp/pear + +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +WORKDIR /var/www/html + +CMD ["php-fpm"] \ No newline at end of file diff --git a/docker/php-fpm-3/zz-docker.conf b/docker/php-fpm-3/zz-docker.conf new file mode 100644 index 000000000..8a6e3e06f --- /dev/null +++ b/docker/php-fpm-3/zz-docker.conf @@ -0,0 +1,8 @@ +[global] +daemonize = no + +[www] +listen = /sock-3/docker.sock +listen.owner = %REPLACE_USERNAME% +listen.group = %REPLACE_USERNAME% +listen.mode = 0660 \ No newline at end of file