2022-12-20
This commit is contained in:
@ -6,6 +6,7 @@ use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use function Safe\{json_decode, file_get_contents};
|
||||
use ProVM\Alias\Controller\Json;
|
||||
use ProVM\Implement\Path;
|
||||
|
||||
class Base
|
||||
{
|
||||
@ -13,12 +14,8 @@ class Base
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, ContainerInterface $container): ResponseInterface
|
||||
{
|
||||
$folder = $container->get('folders')->documentation;
|
||||
$filename = implode(DIRECTORY_SEPARATOR, [
|
||||
$folder,
|
||||
'base.json'
|
||||
]);
|
||||
$documentation = json_decode(file_get_contents($filename));
|
||||
$filename = $container->get('documentation');
|
||||
$documentation = json_decode(trim(file_get_contents($filename)));
|
||||
return $this->withJson($response, $documentation);
|
||||
}
|
||||
}
|
||||
|
16
api/common/Controller/Categorias.php
Normal file
16
api/common/Controller/Categorias.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace Common\Controller;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use ProVM\Alias\API\Controller;
|
||||
use Contabilidad\Repository\Categoria;
|
||||
|
||||
class Categorias extends Controller
|
||||
{
|
||||
public function setup(ContainerInterface $container): void
|
||||
{
|
||||
$this->setSingular('categoria')
|
||||
->setPlural('categorias')
|
||||
->setRepository($container->get(Categoria::class));
|
||||
}
|
||||
}
|
16
api/common/Controller/Conecciones.php
Normal file
16
api/common/Controller/Conecciones.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace Common\Controller;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use ProVM\Alias\API\Controller;
|
||||
use Contabilidad\Repository\Coneccion;
|
||||
|
||||
class Conecciones extends Controller
|
||||
{
|
||||
public function setup(ContainerInterface $container): void
|
||||
{
|
||||
$this->setSingular('coneccion')
|
||||
->setPlural('conecciones')
|
||||
->setRepository($container->get(Coneccion::class));
|
||||
}
|
||||
}
|
@ -1,125 +1,16 @@
|
||||
<?php
|
||||
namespace Common\Controller;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use PDOException;
|
||||
use function Safe\{json_decode,error_log};
|
||||
use ProVM\Alias\Controller\Json;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use ProVM\Alias\API\Controller;
|
||||
use Contabilidad\Repository\Cuenta;
|
||||
|
||||
class Cuentas
|
||||
class Cuentas extends Controller
|
||||
{
|
||||
use Json;
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, Cuenta $repository): ResponseInterface
|
||||
public function setup(ContainerInterface $container): void
|
||||
{
|
||||
$cuentas = [];
|
||||
try {
|
||||
$cuentas = $repository->fetchAll();
|
||||
} catch (PDOException $e) {
|
||||
error_log($e);
|
||||
}
|
||||
return $this->withJson($response, compact('cuentas'));
|
||||
}
|
||||
public function get(ServerRequestInterface $request, ResponseInterface $response, Cuenta $repository, $cuenta_id): ResponseInterface
|
||||
{
|
||||
$cuenta = null;
|
||||
try {
|
||||
$cuenta = $repository->fetchById($cuenta_id);
|
||||
} catch (PDOException $e) {
|
||||
error_log($e);
|
||||
}
|
||||
return $this->withJson($response, compact('cuenta'));
|
||||
}
|
||||
public function add(ServerRequestInterface $request, ResponseInterface $response, Cuenta $repository): ResponseInterface
|
||||
{
|
||||
$body = $request->getBody();
|
||||
$contents = $body->getContents();
|
||||
$json = json_decode($contents);
|
||||
if (!is_array($json)) {
|
||||
$json = [$json];
|
||||
}
|
||||
$output = [
|
||||
'input' => $json,
|
||||
'cuentas' => []
|
||||
];
|
||||
foreach ($json as $data) {
|
||||
$cuenta = $repository->create((array) $data);
|
||||
$status = true;
|
||||
$exists = true;
|
||||
if ($cuenta->isNew()) {
|
||||
$exists = false;
|
||||
try {
|
||||
$repository->save($cuenta);
|
||||
} catch (PDOException $e) {
|
||||
error_log($e);
|
||||
$status = false;
|
||||
}
|
||||
}
|
||||
$output['cuentas'] []= [
|
||||
'cuenta' => $cuenta,
|
||||
'exists' => $exists,
|
||||
'added' => $status
|
||||
];
|
||||
}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function edit(ServerRequestInterface $request, ResponseInterface $response, Cuenta $repository): ResponseInterface
|
||||
{
|
||||
$body = $request->getBody();
|
||||
$contents = $body->getContents();
|
||||
$json = json_decode($contents);
|
||||
if (!is_array($json)) {
|
||||
$json = [$json];
|
||||
}
|
||||
$output = [
|
||||
'input' => $json,
|
||||
'cuentas' => []
|
||||
];
|
||||
foreach ($json as $data) {
|
||||
$cuenta = $repository->fetchById($data->id);
|
||||
$old = clone $cuenta;
|
||||
try {
|
||||
$cuenta->edit((array) $data);
|
||||
$status = $cuenta->isDirty();
|
||||
if ($status) {
|
||||
$repository->save($cuenta);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
error_log($e);
|
||||
$status = false;
|
||||
}
|
||||
$output['cuentas'] []= [
|
||||
'antes' => $old,
|
||||
'cuenta' => $cuenta,
|
||||
'edited' => $status
|
||||
];
|
||||
}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function editOne(ServerRequestInterface $request, ResponseInterface $response, Cuenta $repository, $cuenta_id): ResponseInterface
|
||||
{
|
||||
$cuenta = $repository->fetchById($cuenta_id);
|
||||
$body = $request->getBody();
|
||||
$contents = $body->getContents();
|
||||
$json = json_decode($contents, JSON_OBJECT_AS_ARRAY);
|
||||
$output = [
|
||||
'input' => $json,
|
||||
'old' => clone $cuenta
|
||||
];
|
||||
try {
|
||||
$cuenta->edit((array) $json);
|
||||
$status = $cuenta->isDirty();
|
||||
if ($status) {
|
||||
$repository->save($cuenta);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
error_log($e);
|
||||
$status = false;
|
||||
}
|
||||
$output['cuenta'] = $cuenta;
|
||||
$output['edited'] = $status;
|
||||
return $this->withJson($response, $output);
|
||||
$this->setSingular('cuenta')
|
||||
->setPlural('cuentas')
|
||||
->setRepository($container->get(Cuenta::class));
|
||||
}
|
||||
}
|
||||
|
17
api/common/Controller/Estado/Conecciones.php
Normal file
17
api/common/Controller/Estado/Conecciones.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace Common\Controller\Estado;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use ProVM\Alias\API\Controller;
|
||||
use Contabilidad\Repository\Estado\Coneccion;
|
||||
|
||||
class Conecciones extends Controller
|
||||
{
|
||||
|
||||
public function setup(ContainerInterface $container): void
|
||||
{
|
||||
$this->setSingular('estado_coneccion')
|
||||
->setPlural('estados_conecciones')
|
||||
->setRepository($container->get(Coneccion::class));
|
||||
}
|
||||
}
|
16
api/common/Controller/Monedas.php
Normal file
16
api/common/Controller/Monedas.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace Common\Controller;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use ProVM\Alias\API\Controller;
|
||||
use Contabilidad\Repository\Moneda;
|
||||
|
||||
class Monedas extends Controller
|
||||
{
|
||||
public function setup(ContainerInterface $container): void
|
||||
{
|
||||
$this->setSingular('moneda');
|
||||
$this->setPlural('monedas');
|
||||
$this->setRepository($container->get(Moneda::class));
|
||||
}
|
||||
}
|
16
api/common/Controller/Transacciones.php
Normal file
16
api/common/Controller/Transacciones.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace Common\Controller;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use ProVM\Alias\API\Controller;
|
||||
use Contabilidad\Repository\Transaccion;
|
||||
|
||||
class Transacciones extends Controller
|
||||
{
|
||||
public function setup(ContainerInterface $container): void
|
||||
{
|
||||
$this->setSingular('transaccion');
|
||||
$this->setPlural('transacciones');
|
||||
$this->setRepository($container->get(Transaccion::class));
|
||||
}
|
||||
}
|
44
api/common/Middleware/Error.php
Normal file
44
api/common/Middleware/Error.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace Common\Middleware;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Throwable;
|
||||
use Slim\App;
|
||||
use Slim\Interfaces\ErrorHandlerInterface;
|
||||
use function Safe\error_log;
|
||||
|
||||
class Error implements ErrorHandlerInterface
|
||||
{
|
||||
public function __construct(App $app)
|
||||
{
|
||||
$this->setApp($app);
|
||||
}
|
||||
|
||||
protected App $app;
|
||||
public function setApp(App $app): Error
|
||||
{
|
||||
$this->app = $app;
|
||||
return $this;
|
||||
}
|
||||
public function getApp(): App
|
||||
{
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, Throwable $exception, bool $displayErrorDetails, bool $logErrors, bool $logErrorDetails): ResponseInterface
|
||||
{
|
||||
error_log($exception);
|
||||
$response = $this->getApp()->getResponseFactory()->createResponse($exception->getCode());
|
||||
$output = json_encode([
|
||||
'uri' => $request->getUri()->getPath(),
|
||||
'code' => $exception->getCode(),
|
||||
'message' => $exception->getMessage(),
|
||||
'file' => $exception->getFile(),
|
||||
'line' => $exception->getLine(),
|
||||
'trace' => $exception->getTrace()
|
||||
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
$response->getBody()->write($output);
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
}
|
@ -1,36 +1,74 @@
|
||||
<?php
|
||||
namespace Common\Service;
|
||||
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use DI\NotFoundException;
|
||||
|
||||
class Auth {
|
||||
protected string $key;
|
||||
public function __construct(string $api_key) {
|
||||
public function __construct(string $api_key)
|
||||
{
|
||||
$this->key = $api_key;
|
||||
}
|
||||
public function isValid(Request $request): bool {
|
||||
if ($request->hasHeader('Authorization')) {
|
||||
$sent_key = $this->getAuthKey($request->getHeader('Authorization'));
|
||||
return $this->key == $sent_key;
|
||||
public function isValid(Request $request): bool
|
||||
{
|
||||
return $this->key == $this->getKey($request);
|
||||
}
|
||||
public function getKey(Request $request): string
|
||||
{
|
||||
$errors = [];
|
||||
try {
|
||||
return $this->getHeaderKey($request);
|
||||
} catch (NotFoundExceptionInterface $e) {
|
||||
$errors []= $e;
|
||||
}
|
||||
try {
|
||||
return $this->getBodyKey($request);
|
||||
} catch (NotFoundExceptionInterface $e) {
|
||||
$errors []= $e;
|
||||
}
|
||||
try {
|
||||
return $this->getQueryKey($request);
|
||||
} catch (NotFoundExceptionInterface $e) {
|
||||
$errors []= $e;
|
||||
}
|
||||
throw new NotFoundException('API Key not found.');
|
||||
}
|
||||
protected function getHeaderKey(Request $request): string
|
||||
{
|
||||
if ($request->hasHeader('Authorization')) {
|
||||
return $this->getAuthKey($request->getHeader('Authorization'));
|
||||
}
|
||||
throw new NotFoundException('API Key not found on header');
|
||||
}
|
||||
protected function getBodyKey(Request $request): string
|
||||
{
|
||||
if (isset($request->getParsedBody()['api_key'])) {
|
||||
$sent_key = $request->getParsedBody()['api_key'];
|
||||
return $this->key == $sent_key;
|
||||
return $request->getParsedBody()['api_key'];
|
||||
}
|
||||
$post = $request->getParsedBody() ?? json_decode($request->getBody());
|
||||
$sent_key = $this->getArrayKey($post);
|
||||
if ($sent_key !== null) {
|
||||
return $this->key == $sent_key;
|
||||
try {
|
||||
return $this->getArrayKey($post);
|
||||
} catch (\Exception $e) {
|
||||
throw new NotFoundException('API Key not found in body.');
|
||||
}
|
||||
$sent_key = $this->getArrayKey($request->getQueryParams());
|
||||
return $this->key == $sent_key;
|
||||
}
|
||||
protected function getAuthKey($auth) {
|
||||
protected function getQueryKey(Request $request): string
|
||||
{
|
||||
try {
|
||||
return $this->getArrayKey($request->getQueryParams());
|
||||
} catch (\Exception $e) {
|
||||
throw new NotFoundException('API Key not found in query.');
|
||||
}
|
||||
}
|
||||
protected function getAuthKey($auth)
|
||||
{
|
||||
if (is_array($auth)) {
|
||||
$auth = $auth[0];
|
||||
}
|
||||
if (str_contains($auth, 'Bearer')) {
|
||||
$auth = explode(' ', $auth)[1];
|
||||
$auth = trim(str_replace('Bearer', '', $auth), ' ,');
|
||||
}
|
||||
return $auth;
|
||||
}
|
||||
|
60
api/common/Service/Documenter.php
Normal file
60
api/common/Service/Documenter.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace Common\Service;
|
||||
|
||||
use function Safe\{json_encode, json_decode, file_get_contents, file_put_contents};
|
||||
use ProVM\Concept\API\Route\Route;
|
||||
use ProVM\Implement\API\Route\Route as RouteObj;
|
||||
|
||||
class Documenter
|
||||
{
|
||||
public function __construct(string $filename)
|
||||
{
|
||||
$this->setFilename($filename);
|
||||
}
|
||||
|
||||
protected string $filename;
|
||||
public function setFilename(string $filename): Documenter
|
||||
{
|
||||
$this->filename = $filename;
|
||||
return $this;
|
||||
}
|
||||
public function getFilename(): string
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
protected array $routes;
|
||||
public function setRoutes(array $routes): Documenter
|
||||
{
|
||||
foreach ($routes as $path => $route) {
|
||||
$this->addRoute($path, $route);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function addRoute(string $path, Route $route): Documenter
|
||||
{
|
||||
$this->routes[$path] = $route;
|
||||
return $this;
|
||||
}
|
||||
public function getRoutes(): array
|
||||
{
|
||||
return $this->routes;
|
||||
}
|
||||
|
||||
protected function load(): mixed
|
||||
{
|
||||
$json = json_decode(trim(file_get_contents($this->getFilename())), JSON_OBJECT_AS_ARRAY);
|
||||
foreach ($json['paths'] as $path => $data) {
|
||||
$route = RouteObj::add($data);
|
||||
$this->addRoute($path, $route);
|
||||
}
|
||||
return $json;
|
||||
}
|
||||
public function save(): void
|
||||
{
|
||||
$json = $this->load();
|
||||
$json['paths'] = $this->getRoutes();
|
||||
ksort($json['paths']);
|
||||
file_put_contents($this->getFilename(), json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
}
|
179
api/common/Service/Router.php
Normal file
179
api/common/Service/Router.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
namespace Common\Service;
|
||||
|
||||
use Slim\App;
|
||||
use ProVM\Concept\API\Controller;
|
||||
use ProVM\Implement\API\Route\Route;
|
||||
|
||||
class Router
|
||||
{
|
||||
public function __construct(App &$app, Documenter $documenter)
|
||||
{
|
||||
$this->setApp($app);
|
||||
$this->setDocumenter($documenter);
|
||||
}
|
||||
|
||||
protected App $app;
|
||||
public function setApp(App &$app): Router
|
||||
{
|
||||
$this->app = $app;
|
||||
return $this;
|
||||
}
|
||||
public function getApp(): App
|
||||
{
|
||||
return $this->app;
|
||||
}
|
||||
protected Documenter $documenter;
|
||||
public function setDocumenter(Documenter $documenter): Router
|
||||
{
|
||||
$this->documenter = $documenter;
|
||||
return $this;
|
||||
}
|
||||
public function getDocumenter(): Documenter
|
||||
{
|
||||
return $this->documenter;
|
||||
}
|
||||
protected Controller $controller;
|
||||
public function setController(Controller $controller): Router
|
||||
{
|
||||
$this->controller = $controller;
|
||||
return $this;
|
||||
}
|
||||
public function getController(): Controller
|
||||
{
|
||||
return $this->controller;
|
||||
}
|
||||
|
||||
protected function document(): void
|
||||
{
|
||||
$docs = [
|
||||
"/{$this->getController()->getPlural()}" => [
|
||||
'get' => [
|
||||
'description' => "Entrega una lista de {$this->getController()->getPlural()}",
|
||||
'responses' => [
|
||||
'200' => [
|
||||
'description' => "Lista de {$this->getController()->getPlural()}"
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"/{$this->getController()->getPlural()}/add" => [
|
||||
'post' => [
|
||||
'description' => "Agregar {$this->getController()->getPlural()} con una lista",
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => $this->getController()->getPlural(),
|
||||
'in' => 'query',
|
||||
'description' => 'Lista de datos para agregar',
|
||||
'required' => true
|
||||
]
|
||||
],
|
||||
'responses' => [
|
||||
'200' => [
|
||||
'description' => "Entrega un listado de {$this->getController()->getPlural()} y si fueron agregadas"
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"/{$this->getController()->getPlural()}/edit" => [
|
||||
'put' => [
|
||||
'description' => "Editar multiples {$this->getController()->getPlural()} con una lista",
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => $this->getController()->getPlural(),
|
||||
'in' => 'query',
|
||||
'description' => 'Lista de datos para editar',
|
||||
'required' => true
|
||||
]
|
||||
],
|
||||
'responses' => [
|
||||
'200' => [
|
||||
'description' => "Entrega un listado de {$this->getController()->getPlural()} identificando si fueron editados"
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"/{$this->getController()->getSingular()}/{model_id}" => [
|
||||
'get' => [
|
||||
'description' => "Entrega {$this->getController()->getSingular()}",
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => 'id',
|
||||
'in' => 'path',
|
||||
'description' => "{$this->getController()->getSingular()} id",
|
||||
'required' => true
|
||||
]
|
||||
],
|
||||
'responses' => [
|
||||
'200' => [
|
||||
'description' => "{$this->getController()->getSingular()} found or null"
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"/{$this->getController()->getSingular()}/{model_id}/edit" => [
|
||||
'put' => [
|
||||
'description' => '',
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => 'model_id',
|
||||
'in' => 'path',
|
||||
'description' => "{$this->getController()->getSingular()} id",
|
||||
'required' => true
|
||||
],
|
||||
[
|
||||
'name' => "{$this->getController()->getSingular()}",
|
||||
'in' => 'query',
|
||||
'description' => '',
|
||||
'required' => true
|
||||
]
|
||||
],
|
||||
'responses' => [
|
||||
'200' => [
|
||||
'description' => ''
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"/{$this->getController()->getSingular()}/{model_id}/remove" => [
|
||||
'delete' => [
|
||||
'description' => '',
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => 'model_id',
|
||||
'in' => 'path',
|
||||
'description' => "{$this->getController()->getSingular()} id",
|
||||
'required' => true
|
||||
]
|
||||
],
|
||||
'responses' => [
|
||||
'200' => [
|
||||
'description' => ''
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
foreach ($docs as $path => $r) {
|
||||
$route = Route::add($r);
|
||||
$this->getDocumenter()->addRoute($path, $route);
|
||||
}
|
||||
$this->getDocumenter()->save();
|
||||
}
|
||||
public function build(): void
|
||||
{
|
||||
$this->getApp()->group('/' . $this->getController()->getPlural(), function($app) {
|
||||
$app->post('/add[/]', [get_class($this->getController()), 'add']);
|
||||
$app->put('/edit[/]', [get_class($this->getController()), 'edit']);
|
||||
$app->get('[/]', get_class($this->getController()));
|
||||
});
|
||||
$this->getApp()->group('/' . $this->getController()->getSingular() . '/{model_id}', function($app) {
|
||||
$app->put('/edit[/]', [get_class($this->getController()), 'editOne']);
|
||||
$app->delete('/remove[/]', [get_class($this->getController()), 'remove']);
|
||||
$app->get('[/]', [get_class($this->getController()), 'get']);
|
||||
});
|
||||
|
||||
$this->document();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user