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

ДЗ №19: Работа с очередью #1155

Open
wants to merge 2 commits into
base: main
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
5 changes: 5 additions & 0 deletions hw19/.docker/nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM nginx

WORKDIR /var/www/html

COPY ngnix.conf /etc/nginx/nginx.conf
25 changes: 25 additions & 0 deletions hw19/.docker/nginx/ngnix.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
worker_processes 1;

events {
worker_connections 1024;
}

http {
server {
listen 80;
server_name localhost;
root /var/www/html/public/;

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

location ~ \.php$ {
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
11 changes: 11 additions & 0 deletions hw19/.docker/php-fpm/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM php:8.2-fpm

RUN apt-get update && apt-get install -y \
libzip-dev \
&& docker-php-ext-install zip sockets

RUN chown -R www-data:www-data /var/www/html

WORKDIR /var/www/html

CMD ["php-fpm"]
12 changes: 12 additions & 0 deletions hw19/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Работа с очередью

## Отправка данных
1. Для генерации банковской выписки за указанные даты перейдите в браузере на главную страницу http://localhost/
2. Выберите нужный интервал дат
3. Нажмите кнопку отправить
4. После чего форма вас переадресует на страницу обработчика формы /formHandler, в котором даты отправятся через RabbitMQ Producer в очередь

## Получение данных
1. Чтобы считать данную очередь, вам нужно зайти в консоль и запуcтить команду php bin/console rabbitmq:consumer
2. Теперь в консоли вы можете видеть отправленные из браузерной формы даты
3. Также в консольной команде после вывода данных на экран происходит отправка письма.
36 changes: 36 additions & 0 deletions hw19/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
version: "3"
services:
nginx:
container_name: nginx-otusphp
build: ./.docker/nginx
ports:
- "80:80"
volumes:
- ./www:/var/www/html
depends_on:
- php-fpm
networks:
- otusphp

php-fpm:
container_name: php-fpm-otusphp
build: ./.docker/php-fpm/
volumes:
- ./www:/var/www/html
depends_on:
- rabbitmq
networks:
- otusphp

rabbitmq:
container_name: rabbitmq-otusphp
image: rabbitmq:3.10.7-management
ports:
- 15672:15672
- 5672:5672
networks:
- otusphp

networks:
otusphp:
driver: bridge
14 changes: 14 additions & 0 deletions hw19/www/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
BROKER_CONNECT='Shabanov\Otusphp\Connection\RabbitMqConnect'
BROKER_HOST='rabbitmq'
BROKER_PORT=5672
BROKER_USER='guest'
BROKER_PASSWORD='guest'
EXCHANGE='shabanov'
QUEUE='otus'

EMAIL_SMTP='smtp.yandex.ru'
EMAIL_PORT=465
EMAIL_USER='saveliy'
EMAIL_PASSWORD='123456'
EMAIL_FROM='[email protected]'
EMAIL_TO='[email protected]'
20 changes: 20 additions & 0 deletions hw19/www/bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env php
<?php
declare(strict_types=1);

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

use Shabanov\Otusphp\Command\ConsumerCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Dotenv\Dotenv;

$dotenv = new Dotenv();
$dotenv->load(__DIR__ . '/../.env');

$application = new Application();
$application->add(new ConsumerCommand(new $_ENV['BROKER_CONNECT']()));
try {
$application->run();
} catch (Exception $e) {
throw new \Exception($e->getMessage());
}
21 changes: 21 additions & 0 deletions hw19/www/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "shabanov/otusphp",
"autoload": {
"psr-4": {
"Shabanov\\Otusphp\\": "src/"
}
},
"authors": [
{
"name": "Vyacheslav Shabanov",
"email": "[email protected]"
}
],
"require": {
"php-amqplib/php-amqplib": "^3.6",
"symfony/console": "^7.0",
"symfony/mailer": "^7.0",
"symfony/dotenv": "^7.0",
"phpmailer/phpmailer": "^6.9"
}
}
13 changes: 13 additions & 0 deletions hw19/www/public/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

Check failure on line 1 in hw19/www/public/index.php

View workflow job for this annotation

GitHub Actions / phpcs

Header blocks must be separated by a single blank line
declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';

use Shabanov\Otusphp\App;

try {
$app = new App();
$app();
} catch(Exception $e) {

Check failure on line 11 in hw19/www/public/index.php

View workflow job for this annotation

GitHub Actions / phpcs

Expected 1 space(s) after CATCH keyword; 0 found
throw new Exception($e->getMessage());
}
20 changes: 20 additions & 0 deletions hw19/www/src/App.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

Check failure on line 1 in hw19/www/src/App.php

View workflow job for this annotation

GitHub Actions / phpcs

Header blocks must be separated by a single blank line
declare(strict_types=1);

namespace Shabanov\Otusphp;

use Symfony\Component\Dotenv\Dotenv;

class App
{
public function __construct()
{
$dotenv = new Dotenv();
$dotenv->load(__DIR__ . '/../.env');
}

public function __invoke(): void
{
(new Route($_SERVER['REQUEST_URI']))->run();
}
}
38 changes: 38 additions & 0 deletions hw19/www/src/Command/ConsumerCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

Check failure on line 1 in hw19/www/src/Command/ConsumerCommand.php

View workflow job for this annotation

GitHub Actions / phpcs

Header blocks must be separated by a single blank line
declare(strict_types=1);

namespace Shabanov\Otusphp\Command;

use PhpAmqpLib\Channel\AbstractChannel;
use PhpAmqpLib\Channel\AMQPChannel;
use Shabanov\Otusphp\Connection\ConnectionInterface;
use Shabanov\Otusphp\Consumer\RabbitMqConsumer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class ConsumerCommand extends Command
{
private string $queue;
private AMQPChannel|AbstractChannel $channel;

public function __construct(private readonly ConnectionInterface $connect)
{
parent::__construct();
$this->channel = $this->connect->getClient();
$this->queue = $_ENV['QUEUE'];
}

protected function configure(): void
{
$this->setName('rabbitmq:consumer')
->setDescription('RabbitMQ consumer обработчик формы');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
(new RabbitMqConsumer($this->connect, $output))->run();

return Command::SUCCESS;
}
}
10 changes: 10 additions & 0 deletions hw19/www/src/Connection/ConnectionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Shabanov\Otusphp\Connection;

interface ConnectionInterface
{
public function getClient();

public function close(): void;
}
37 changes: 37 additions & 0 deletions hw19/www/src/Connection/RabbitMqConnect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Shabanov\Otusphp\Connection;

use Exception;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Channel\AbstractChannel;

class RabbitMqConnect implements ConnectionInterface
{
private AMQPStreamConnection $connect;
/**
* @throws Exception
*/
public function __construct()
{
$this->connect = new AMQPStreamConnection(
$_ENV['BROKER_HOST'],
$_ENV['BROKER_PORT'],
$_ENV['BROKER_USER'],
$_ENV['BROKER_PASSWORD']
);
}
public function getClient(): AMQPChannel|AbstractChannel
{
return $this->connect->channel();
}

/**
* @throws Exception
*/
public function close(): void
{
$this->connect->close();
}
}
61 changes: 61 additions & 0 deletions hw19/www/src/Consumer/RabbitMqConsumer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

Check failure on line 1 in hw19/www/src/Consumer/RabbitMqConsumer.php

View workflow job for this annotation

GitHub Actions / phpcs

Header blocks must be separated by a single blank line
declare(strict_types=1);

namespace Shabanov\Otusphp\Consumer;

use PhpAmqpLib\Channel\AbstractChannel;
use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Message\AMQPMessage;
use Shabanov\Otusphp\Connection\ConnectionInterface;
use Shabanov\Otusphp\Mail\Mailer;
use Symfony\Component\Console\Output\OutputInterface;

class RabbitMqConsumer
{
private AMQPChannel|AbstractChannel $channel;
private string $queue;

public function __construct(private readonly ConnectionInterface $connect,

Check failure on line 18 in hw19/www/src/Consumer/RabbitMqConsumer.php

View workflow job for this annotation

GitHub Actions / phpcs

The first parameter of a multi-line function declaration must be on the line after the opening bracket
private readonly OutputInterface $output

Check failure on line 19 in hw19/www/src/Consumer/RabbitMqConsumer.php

View workflow job for this annotation

GitHub Actions / phpcs

Multi-line function declaration not indented correctly; expected 8 spaces but found 32
) {
$this->channel = $this->connect->getClient();
$this->queue = $_ENV['QUEUE'];
}

public function run(): void
{
$this->channel->basic_consume(
$this->queue,
'',
false,
true,
false,
false,
[$this, 'consumeHandler']
);

while ($this->channel->is_consuming()) {
$this->channel->wait();
}

$this->close();
}

public function consumeHandler(AMQPMessage $message): void
{
/**
* Выведим в консоль данные
*/
$this->output->writeln('<info>[x] ' . $message->body . '</info>');
/**
* Отправим строку на Email
*/
(new Mailer($message->body))->send();
}

private function close(): void
{
$this->channel->close();
$this->connect->close();
}
}
26 changes: 26 additions & 0 deletions hw19/www/src/Controller/PageController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

Check failure on line 1 in hw19/www/src/Controller/PageController.php

View workflow job for this annotation

GitHub Actions / phpcs

Header blocks must be separated by a single blank line
declare(strict_types=1);

namespace Shabanov\Otusphp\Controller;

use Shabanov\Otusphp\Producer\RabbitMqProducer;
use Shabanov\Otusphp\Render\FormRender;
use Shabanov\Otusphp\Render\FormSuccessRender;

class PageController
{
public function main(): void
{
echo (new FormRender())->show();
}

public function formHandler(): void
{
if (!empty($_REQUEST['send']) && !empty($_REQUEST['date_from'])) {
$message = 'Date from: ' . $_REQUEST['date_from'] . ' Date to: ' . $_REQUEST['date_to'];
(new RabbitMqProducer(new $_ENV['BROKER_CONNECT']()))
->send($message);
echo (new FormSuccessRender())->show();
}
}
}
Loading
Loading