Skip to content
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
18 changes: 18 additions & 0 deletions app/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "rsm/app",
"type": "project",
"authors": [
{
"name": "yessaliyev",
"email": "40271311+yessaliyev@users.noreply.github.com"
}
],
"require": {
"php": ">=7.4"
},
"autoload": {
"psr-4": {
"App\\": "src"
}
}
}
20 changes: 20 additions & 0 deletions app/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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

require '../vendor/autoload.php';

use App\App;
use App\Response;

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

namespace App;

use App\Bracket\BracketValidator;
use App\Exceptions\RequestException;

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

if (empty($data['string'])) {
throw new RequestException('Не передан string', 400);
}

$validator = new BracketValidator($data['string']);
$validator->check();
}
}
42 changes: 42 additions & 0 deletions app/src/Bracket/BracketValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace App\Bracket;

use App\Exceptions\RequestException;
use App\Response;

class BracketValidator
{
private array $brackets;

public function __construct(string $brackets)
{
$this->brackets = str_split($brackets);
}

public function check()
{
if (!$this->validate()) {
throw new RequestException('invalid format', 400);
}

Response::send(200, 'correct');
}

private function validate() : bool
{
if (empty($this->brackets)) {
return false;
}

$counter = 0;
foreach ($this->brackets as $bracket) {
if ($bracket === '(') {
$counter++;
} else {
$counter--;
}
}
return $counter === 0 && end($this->brackets) !== '(';
}
}
13 changes: 13 additions & 0 deletions app/src/Exceptions/RequestException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Exceptions;

use Throwable;

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

namespace App;

use App\Exceptions\RequestException;

class Request
{
private array $data;

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

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

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

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

namespace App;

class Response
{
public static function send($code = 200, $message = '', $data = [])
{

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

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

$data['status'] = $code < 300 ? "success" : "error";
$data['message'] = $message;
echo json_encode($data);
}
}
29 changes: 29 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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:/sock
ports:
- "8787:80"

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



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
21 changes: 21 additions & 0 deletions docker/nginx/mysite.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
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 unix:/sock/docker.sock;
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;
}
40 changes: 40 additions & 0 deletions docker/nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -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;

}
50 changes: 50 additions & 0 deletions docker/php-fpm/Dockerfile
Original file line number Diff line number Diff line change
@@ -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"]
8 changes: 8 additions & 0 deletions docker/php-fpm/zz-docker.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[global]
daemonize = no

[www]
listen = /sock/docker.sock
listen.owner = %REPLACE_USERNAME%
listen.group = %REPLACE_USERNAME%
listen.mode = 0660