diff --git a/.htaccess b/.htaccess new file mode 100644 index 00000000..a174a4a7 --- /dev/null +++ b/.htaccess @@ -0,0 +1,7 @@ +RewriteEngine On + +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d + +RewriteCond %{REQUEST_URI} ^/index\.php/(.*)$ +RewriteRule ^index\.php/(.*)$ /index.php?url=$1 [QSA,L] \ No newline at end of file diff --git a/composer.json b/composer.json index ce7dfb19..0c067e6b 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "Desafio para candidatos a back-end.", "type": "project", "require": { - "php": ">= 7.4" + "php": ">= 8.1.2" }, "require-dev": { "squizlabs/php_codesniffer": "^3.4", diff --git a/src/ExchangeController.php b/src/ExchangeController.php new file mode 100644 index 00000000..6197d515 --- /dev/null +++ b/src/ExchangeController.php @@ -0,0 +1,81 @@ + + * @license http://opensource.org/licenses/MIT MIT + * @link https://github.com/apiki/back-end-challenge + */ + +namespace App; + +use App\Response; + +/** + * Controlador para operações de conversão de moedas. + * + * Esta classe é responsável por processar solicitações de conversão + * entre diferentes moedas suportadas pela API, validando os parâmetros + * de entrada e retornando respostas formatadas. + * + * @category Challenge + * @package Back-end + * @author Gustavo Dias + * @license http://opensource.org/licenses/MIT MIT + * @link https://github.com/apiki/back-end-challenge + * @since 1.0.0 + */ +class ExchangeController +{ + /** + * Converte um valor de uma moeda para outra. + * + * Este método processa os parâmetros de conversão, valida se a conversão + * é suportada entre as moedas especificadas, calcula o valor convertido + * usando a taxa fornecida e retorna uma resposta JSON formatada. + * + * @param array $params Array com os + * parâmetros: [0=>route, + * 1=>amount, 2=>from, + * 3=>to, 4=>rate] + * + * @return void + */ + public static function convert(array $params) + { + + $amount = floatval($params[1]); + $from = strtoupper($params[2]); + $to = strtoupper($params[3]); + $rate = floatval($params[4]); + + $supportedCurrencies = [ + 'BRL' => ['EUR', 'USD'], + 'EUR' => ['BRL'], + 'USD' => ['BRL'] + ]; + + $symbols = [ + 'BRL' => 'R$', + 'USD' => '$', + 'EUR' => '€' + ]; + + if (!isset($supportedCurrencies[$from]) + || !in_array($to, $supportedCurrencies[$from]) + ) { + Response::exchangeNotSupported($from, $supportedCurrencies[$from]); + return; + } + + $convertedAmount = $amount * $rate; + + Response::exchangeOk($convertedAmount, $symbols[$to]); + } +} diff --git a/src/Response.php b/src/Response.php new file mode 100644 index 00000000..7aee3b09 --- /dev/null +++ b/src/Response.php @@ -0,0 +1,99 @@ + + * @license http://opensource.org/licenses/MIT MIT + * @link https://github.com/apiki/back-end-challenge + */ + +namespace App; + +/** + * Classe utilitária para gerenciar respostas HTTP em formato JSON. + * + * Esta classe fornece métodos estáticos para padronizar as respostas + * da API, incluindo códigos de status HTTP apropriados e formatação + * consistente das mensagens de resposta. + * + * @category Challenge + * @package Back-end + * @author Gustavo Dias + * @license http://opensource.org/licenses/MIT MIT + * @link https://github.com/apiki/back-end-challenge + * @since 1.0.0 + */ +class Response +{ + /** + * Envia uma resposta JSON com código de status HTTP. + * + * @param array $data Os dados a serem retornados em formato JSON + * @param int $status O código de status HTTP (padrão: 200) + * + * @return void + */ + public static function json(array $data, int $status = 200) + { + http_response_code($status); + + header("Content-type: application/json"); + + echo json_encode($data); + } + + /** + * Retorna uma resposta JSON para rota não encontrada. + * + * @return void + */ + public static function routeNotFound() + { + self::json(['message' => 'Rota não encontrada!'], 400); + } + + /** + * Retorna uma resposta JSON quando uma moeda não é suportada. + * + * @param string $from A moeda de origem + * @param array $supportedCurrencies Array com as moedas suportadas + * + * @return void + */ + public static function exchangeNotSupported($from, $supportedCurrencies) + { + $formattedCurrencies = implode(', ', $supportedCurrencies); + self::json( + [ + 'message' => "Moedas suportadas para $from : $formattedCurrencies" + ], + 400 + ); + } + + /** + * Retorna uma resposta JSON de sucesso para conversão de moeda. + * + * @param float $convertedAmount O valor convertido + * @param string $symbol O símbolo da moeda de destino + * + * @return void + */ + public static function exchangeOk($convertedAmount, $symbol) + { + self::json( + [ + 'valorConvertido' => $convertedAmount, + 'simboloMoeda' => $symbol + ], + 200 + ); + } +} diff --git a/src/index.php b/src/index.php index 92841bc8..f8a181a2 100644 --- a/src/index.php +++ b/src/index.php @@ -2,17 +2,43 @@ /** * Back-end Challenge. * - * PHP version 7.4 + * PHP version 8.1.2 * * Este será o arquivo chamado na execução dos testes automátizados. * * @category Challenge * @package Back-end - * @author Seu Nome + * @author Gustavo Dias * @license http://opensource.org/licenses/MIT MIT * @link https://github.com/apiki/back-end-challenge */ declare(strict_types=1); +use App\ExchangeController; +use App\Response; + require __DIR__ . '/../vendor/autoload.php'; + +$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); + +if ($uri !== '/' && file_exists(__DIR__ . '/../../' . $uri)) { + Response::routeNotFound(); + return; +} + +$segments = explode('/', trim($uri, '/')); + + +if (!(count($segments) === 5 && $segments[0] === 'exchange')) { + Response::routeNotFound(); + return; +} + +ExchangeController::convert($segments); + + + + + +