Added Tasks to API.

This commit is contained in:
abdulmohsen
2024-03-05 16:11:18 +03:00
parent e157622793
commit 165bcef1ed
6 changed files with 123 additions and 29 deletions

View File

@@ -287,16 +287,6 @@ final class Index
'data' => [],
];
if (0 === $stmt->rowCount()) {
$response['error'] = [
'message' => 'No Results.',
];
if (true === count($response['filters']) >= 1) {
$response['error']['message'] .= ' Probably invalid filters values were used.';
}
}
while ($row = $stmt->fetch()) {
$entity = Container::get(iState::class)->fromArray($row);
$item = $entity->getAll();

63
src/API/Tasks/Index.php Normal file
View File

@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace App\API\Tasks;
use App\Commands\System\TasksCommand;
use App\Libs\Attributes\Route\Get;
use App\Libs\HTTP_STATUS;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
#[Get(self::URL . '[/]', name: 'tasks.index')]
final class Index
{
public const URL = '%{api.prefix}/tasks';
public function __invoke(ServerRequestInterface $request, array $args = []): ResponseInterface
{
$response = [
'data' => [],
];
$apiUrl = $request->getUri()->withHost('')->withPort(0)->withScheme('');
$urlPath = rtrim($request->getUri()->getPath(), '/');
foreach (TasksCommand::getTasks() as $task) {
$response['data'][] = [
'@self' => (string)$apiUrl->withPath($urlPath . '/' . ag($task, 'name')),
...array_filter(
self::formatTask($task),
fn($k) => false === in_array($k, ['command', 'args']),
ARRAY_FILTER_USE_KEY
)
];
}
return api_response($response, HTTP_STATUS::HTTP_OK, []);
}
public static function formatTask(array $task): array
{
$isEnabled = (bool)ag($task, 'enabled', false);
$item = [
'name' => ag($task, 'name'),
'description' => ag($task, 'description'),
'enabled' => $isEnabled,
'timer' => ag($task, 'timer')->getexpression(),
'next_run' => null,
'prev_run' => null,
'command' => ag($task, 'command'),
'args' => ag($task, 'args'),
];
if ($isEnabled) {
$item['next_run'] = makeDate(ag($task, 'timer')->getNextRunDate());
$item['prev_run'] = makeDate(ag($task, 'timer')->getPreviousRunDate());
}
return $item;
}
}

35
src/API/Tasks/View.php Normal file
View File

@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace App\API\Tasks;
use App\Commands\System\TasksCommand;
use App\Libs\Attributes\Route\Get;
use App\Libs\HTTP_STATUS;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
#[Get(Index::URL . '/{id:[a-zA-Z0-9_-]+}[/]', name: 'tasks.view')]
final class View
{
public function __invoke(ServerRequestInterface $request, array $args = []): ResponseInterface
{
if (null === ($id = ag($args, 'id'))) {
return api_error('No id was given.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
$task = TasksCommand::getTasks($id);
if (empty($task)) {
return api_error('Task not found.', HTTP_STATUS::HTTP_NOT_FOUND);
}
$response = [
'@self' => parseConfigValue(Index::URL . '/' . $id),
...Index::formatTask($task)
];
return api_response($response, HTTP_STATUS::HTTP_OK);
}
}

View File

@@ -139,7 +139,7 @@ final class TasksCommand extends Command
$mode = $input->getOption('output');
foreach ($this->getTasks() as $task) {
foreach (self::getTasks() as $task) {
$list[] = [
'name' => $task['name'],
'command' => $task['command'],
@@ -166,7 +166,7 @@ final class TasksCommand extends Command
private function runTasks(iInput $input, iOutput $output): int
{
$run = [];
$tasks = $this->getTasks();
$tasks = self::getTasks();
if (null !== ($task = $input->getOption('task'))) {
$task = strtolower($task);
@@ -316,9 +316,11 @@ final class TasksCommand extends Command
/**
* Get the list of tasks.
*
* @param string|null $name The name of the task to get.
*
* @return array<string, array{name: string, command: string, args: string, description: string, enabled: bool, timer: CronExpression, next: string }> The list of tasks.
*/
private function getTasks(): array
public static function getTasks(string|null $name = null): array
{
$list = [];
@@ -343,6 +345,10 @@ final class TasksCommand extends Command
}
}
if (null !== $name) {
return ag($list, $name, []);
}
return $list;
}

View File

@@ -4,9 +4,7 @@ declare(strict_types=1);
namespace App\Libs\Attributes\Route;
use App\Libs\Config;
use Attribute;
use Closure;
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
class Route
@@ -43,22 +41,12 @@ class Route
) {
$this->name = $name;
$this->methods = $methods;
$this->pattern = $this->fromConfig($pattern);
$this->pattern = parseConfigValue($pattern);
$this->middleware = is_string($middleware) ? [$middleware] : $middleware;
$this->port = null !== $port ? $this->fromConfig($port) : $port;
$this->scheme = null !== $scheme ? $this->fromConfig($scheme) : $scheme;
$this->host = null !== $host ? $this->fromConfig($host, fn($v) => parse_url($v, PHP_URL_HOST)) : $host;
$this->port = null !== $port ? parseConfigValue($port) : $port;
$this->scheme = null !== $scheme ? parseConfigValue($scheme) : $scheme;
$this->host = null !== $host ? parseConfigValue($host, fn($v) => parse_url($v, PHP_URL_HOST)) : $host;
$this->isCli = true === (bool)ag($opts, 'cli', false);
}
private function fromConfig(mixed $value, Closure|null $callback = null): mixed
{
if (is_string($value) && preg_match('#%{(.+?)}#s', $value)) {
$val = preg_replace_callback('#%{(.+?)}#s', fn($match) => Config::get($match[1], $match[1]), $value);
return null !== $callback && null !== $val ? $callback($val) : $val;
}
return $value;
}
}

View File

@@ -1114,3 +1114,15 @@ if (false === function_exists('getSystemMemoryInfo')) {
return $result;
}
}
if (!function_exists('parseConfigValue')) {
function parseConfigValue(mixed $value, Closure|null $callback = null): mixed
{
if (is_string($value) && preg_match('#%{(.+?)}#s', $value)) {
$val = preg_replace_callback('#%{(.+?)}#s', fn($match) => Config::get($match[1], $match[1]), $value);
return null !== $callback && null !== $val ? $callback($val) : $val;
}
return $value;
}
}