refs #518. New endpoint 'search'
parent
7ba4deaafa
commit
b6ade24314
|
@ -1,6 +1,6 @@
|
||||||
api_platform:
|
api_platform:
|
||||||
title: 'OgCore API'
|
title: 'OgCore Api'
|
||||||
description: 'API Documentation for OgCore'
|
description: 'Api Documentation for OgCore'
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
path_segment_name_generator: 'api_platform.path_segment_name_generator.dash'
|
path_segment_name_generator: 'api_platform.path_segment_name_generator.dash'
|
||||||
formats:
|
formats:
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Api;
|
||||||
|
|
||||||
|
use App\Entity\Client;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
class SearchController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/search', methods: ['GET'])]
|
||||||
|
public function index(Request $request, EntityManagerInterface $entityManager): Response
|
||||||
|
{
|
||||||
|
$filters = $request->query->get('filters');
|
||||||
|
if ($filters) {
|
||||||
|
$filters = json_decode($filters, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$repository = $entityManager->getRepository(Client::class);
|
||||||
|
$queryBuilder = $repository->createQueryBuilder('e');
|
||||||
|
|
||||||
|
if (!empty($filters)) {
|
||||||
|
foreach ($filters as $field => $value) {
|
||||||
|
$queryBuilder->andWhere("e.$field = :$field")
|
||||||
|
->setParameter($field, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = $queryBuilder->getQuery()->getResult();
|
||||||
|
|
||||||
|
return new JsonResponse($results);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,63 +15,63 @@ final class ClientInput
|
||||||
#[Assert\NotBlank(message: 'validators.client.name.not_blank')]
|
#[Assert\NotBlank(message: 'validators.client.name.not_blank')]
|
||||||
#[Groups(['client:write'])]
|
#[Groups(['client:write'])]
|
||||||
#[ApiProperty(
|
#[ApiProperty(
|
||||||
description: 'descriptions.client.name',
|
description: 'El nombre del cliente',
|
||||||
example: "examples.client.name",
|
example: 'Cliente 1',
|
||||||
)]
|
)]
|
||||||
public ?string $name = null;
|
public ?string $name = null;
|
||||||
|
|
||||||
#[Groups(['client:write'])]
|
#[Groups(['client:write'])]
|
||||||
#[ApiProperty(
|
#[ApiProperty(
|
||||||
description: 'descriptions.client.serial_number',
|
description: 'La descripción del cliente',
|
||||||
example: "examples.client.serial_number"
|
example: 'Cliente descripcion 1',
|
||||||
)]
|
)]
|
||||||
public ?string $serialNumber = null;
|
public ?string $serialNumber = null;
|
||||||
|
|
||||||
#[Groups(['client:write'])]
|
#[Groups(['client:write'])]
|
||||||
#[ApiProperty(
|
#[ApiProperty(
|
||||||
description: 'descriptions.client.network_interface',
|
description: 'La interfaz de red del cliente',
|
||||||
example: "examples.client.network_interface"
|
example: 'eth0'
|
||||||
)]
|
)]
|
||||||
public ?string $netiface = null;
|
public ?string $netiface = null;
|
||||||
|
|
||||||
#[Groups(['client:write'])]
|
#[Groups(['client:write'])]
|
||||||
#[ApiProperty(
|
#[ApiProperty(
|
||||||
description: 'descriptions.client.network_driver',
|
description: 'El driver de red del cliente',
|
||||||
example: "examples.client.network_driver"
|
example: 'e1000e'
|
||||||
)]
|
)]
|
||||||
public ?string $netDriver = null;
|
public ?string $netDriver = null;
|
||||||
|
|
||||||
#[Groups(['client:write'])]
|
#[Groups(['client:write'])]
|
||||||
#[ApiProperty(
|
#[ApiProperty(
|
||||||
description: 'descriptions.client.mac_address',
|
description: 'La dirección MAC del cliente',
|
||||||
example: "examples.client.mac_address"
|
example: '00:00:00:00:00:00'
|
||||||
)]
|
)]
|
||||||
public ?string $mac = null;
|
public ?string $mac = null;
|
||||||
|
|
||||||
#[Groups(['client:write'])]
|
#[Groups(['client:write'])]
|
||||||
#[Assert\Ip(message: 'validators.ip_address.invalid')]
|
#[Assert\Ip(message: 'validators.ip_address.invalid')]
|
||||||
#[ApiProperty(
|
#[ApiProperty(
|
||||||
description: 'descriptions.client.ip_address',
|
description: 'La dirección IP del cliente',
|
||||||
example: "examples.client.ip_address"
|
example: '192.168.1.1'
|
||||||
)]
|
)]
|
||||||
public ?string $ip = null;
|
public ?string $ip = null;
|
||||||
|
|
||||||
#[Assert\NotNull(message: 'validators.organizational_unit.not_null')]
|
#[Assert\NotNull(message: 'validators.organizational_unit.not_null')]
|
||||||
#[Groups(['client:write', 'client:patch'])]
|
#[Groups(['client:write', 'client:patch'])]
|
||||||
#[ApiProperty(
|
#[ApiProperty(
|
||||||
description: 'descriptions.client.organizational_unit'
|
description: 'La unidad organizativa del cliente'
|
||||||
)]
|
)]
|
||||||
public ?OrganizationalUnitOutput $organizationalUnit = null;
|
public ?OrganizationalUnitOutput $organizationalUnit = null;
|
||||||
|
|
||||||
#[Groups(['client:write'])]
|
#[Groups(['client:write'])]
|
||||||
#[ApiProperty(
|
#[ApiProperty(
|
||||||
description: 'descriptions.client.menu'
|
description: 'El menú del cliente'
|
||||||
)]
|
)]
|
||||||
public ?MenuOutput $menu = null;
|
public ?MenuOutput $menu = null;
|
||||||
|
|
||||||
#[Groups(['client:write'])]
|
#[Groups(['client:write'])]
|
||||||
#[ApiProperty(
|
#[ApiProperty(
|
||||||
description: 'descriptions.client.hardware_profile'
|
description: 'El perfil de hardware del cliente'
|
||||||
)]
|
)]
|
||||||
public ?HardwareProfileOutput $hardwareProfile = null;
|
public ?HardwareProfileOutput $hardwareProfile = null;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
final class HardwareInput
|
final class HardwareInput
|
||||||
{
|
{
|
||||||
#[Assert\NotBlank]
|
#[Assert\NotBlank(message: 'validators.hardware.name.not_blank')]
|
||||||
#[Groups(['hardware:write'])]
|
#[Groups(['hardware:write'])]
|
||||||
#[ApiProperty(description: 'The name of the hardware', example: "Hardware 1")]
|
#[ApiProperty(description: 'The name of the hardware', example: "Hardware 1")]
|
||||||
public ?string $name = null;
|
public ?string $name = null;
|
||||||
|
@ -19,7 +19,7 @@ final class HardwareInput
|
||||||
#[ApiProperty(description: 'The description of the hardware', example: "Hardware 1 description")]
|
#[ApiProperty(description: 'The description of the hardware', example: "Hardware 1 description")]
|
||||||
public ?string $description = null;
|
public ?string $description = null;
|
||||||
|
|
||||||
#[Assert\NotNull]
|
#[Assert\NotNull(message: 'validators.hardware.type.not_null')]
|
||||||
#[Groups(['hardware:write'])]
|
#[Groups(['hardware:write'])]
|
||||||
#[ApiProperty(description: 'The type of the hardware', example: "Server")]
|
#[ApiProperty(description: 'The type of the hardware', example: "Server")]
|
||||||
public ?HardwareTypeOutput $type = null;
|
public ?HardwareTypeOutput $type = null;
|
||||||
|
|
|
@ -8,7 +8,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
class HardwareTypeInput
|
class HardwareTypeInput
|
||||||
{
|
{
|
||||||
#[Assert\NotBlank]
|
#[Assert\NotBlank(message: 'validators.hardware_type.name.not_blank')]
|
||||||
#[Groups(['hardware-type:write'])]
|
#[Groups(['hardware-type:write'])]
|
||||||
public ?string $name = null;
|
public ?string $name = null;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
final class ImageInput
|
final class ImageInput
|
||||||
{
|
{
|
||||||
#[Assert\NotBlank]
|
#[Assert\NotBlank(message: 'validators.image.name.not_blank')]
|
||||||
#[Groups(['image:write'])]
|
#[Groups(['image:write'])]
|
||||||
#[ApiProperty(description: 'The name of the image', example: "Image 1")]
|
#[ApiProperty(description: 'The name of the image', example: "Image 1")]
|
||||||
public ?string $name = null;
|
public ?string $name = null;
|
||||||
|
|
|
@ -18,11 +18,11 @@ class NetworkSettingsInput
|
||||||
#[Groups(['organizational-unit:write'])]
|
#[Groups(['organizational-unit:write'])]
|
||||||
public ?string $proxy = null;
|
public ?string $proxy = null;
|
||||||
|
|
||||||
#[Assert\Ip()]
|
#[Assert\Ip(message: 'validators.network_settings.ip_address.invalid')]
|
||||||
#[Groups(['organizational-unit:write'])]
|
#[Groups(['organizational-unit:write'])]
|
||||||
public ?string $dns = null;
|
public ?string $dns = null;
|
||||||
|
|
||||||
#[Assert\Ip()]
|
#[Assert\Ip(message: 'validators.network_settings.ip_address.invalid')]
|
||||||
#[Groups(['organizational-unit:write'])]
|
#[Groups(['organizational-unit:write'])]
|
||||||
public ?string $netmask = null;
|
public ?string $netmask = null;
|
||||||
|
|
||||||
|
@ -36,15 +36,15 @@ class NetworkSettingsInput
|
||||||
#[Groups(['organizational-unit:write'])]
|
#[Groups(['organizational-unit:write'])]
|
||||||
public ?string $p2pMode = null;
|
public ?string $p2pMode = null;
|
||||||
|
|
||||||
#[Assert\GreaterThan(0)]
|
#[Assert\GreaterThan(0, message: 'validators.network_settings.p2p_time.invalid')]
|
||||||
#[Groups(['organizational-unit:write'])]
|
#[Groups(['organizational-unit:write'])]
|
||||||
public ?int $p2pTime = null;
|
public ?int $p2pTime = null;
|
||||||
|
|
||||||
#[Assert\Ip()]
|
#[Assert\Ip(message: 'validators.network_settings.ip_address.invalid')]
|
||||||
#[Groups(['organizational-unit:write'])]
|
#[Groups(['organizational-unit:write'])]
|
||||||
public ?string $mcastIp = null;
|
public ?string $mcastIp = null;
|
||||||
|
|
||||||
#[Assert\GreaterThan(0)]
|
#[Assert\GreaterThan(0, message: 'validators.network_settings.mcast_speed.invalid')]
|
||||||
#[Groups(['organizational-write:write'])]
|
#[Groups(['organizational-write:write'])]
|
||||||
public ?int $mcastSpeed = null;
|
public ?int $mcastSpeed = null;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
class OperativeSystemInput
|
class OperativeSystemInput
|
||||||
{
|
{
|
||||||
#[Assert\NotBlank]
|
#[Assert\NotBlank(message: 'validators.operative_system.name.not_blank')]
|
||||||
#[Groups(['operative-system:write'])]
|
#[Groups(['operative-system:write'])]
|
||||||
public ?string $name = null;
|
public ?string $name = null;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||||
#[OrganizationalUnitParent]
|
#[OrganizationalUnitParent]
|
||||||
class OrganizationalUnitInput
|
class OrganizationalUnitInput
|
||||||
{
|
{
|
||||||
#[Assert\NotBlank]
|
#[Assert\NotBlank(message: 'validators.organizational_unit.name.not_blank')]
|
||||||
#[Groups(['organizational-unit:write'])]
|
#[Groups(['organizational-unit:write'])]
|
||||||
public ?string $name = null;
|
public ?string $name = null;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ final readonly class OpenApiFactory implements OpenApiFactoryInterface
|
||||||
$openApi = $this->decorated->__invoke($context);
|
$openApi = $this->decorated->__invoke($context);
|
||||||
|
|
||||||
$this->addRefreshToken($openApi);
|
$this->addRefreshToken($openApi);
|
||||||
|
$this->addSearchEndpoint($openApi);
|
||||||
|
|
||||||
|
|
||||||
return $openApi;
|
return $openApi;
|
||||||
}
|
}
|
||||||
|
@ -75,4 +77,53 @@ final readonly class OpenApiFactory implements OpenApiFactoryInterface
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
private function addSearchEndpoint(OpenApi $openApi): void
|
||||||
|
{
|
||||||
|
$openApi
|
||||||
|
->getPaths()
|
||||||
|
->addPath('/search', (new Model\PathItem())->withGet(
|
||||||
|
(new Model\Operation('getSearch'))
|
||||||
|
->withTags(['Search'])
|
||||||
|
->withResponses([
|
||||||
|
Response::HTTP_OK => [
|
||||||
|
'description' => 'Search results',
|
||||||
|
'content' => [
|
||||||
|
'application/json' => [
|
||||||
|
'schema' => [
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => [
|
||||||
|
'results' => [
|
||||||
|
'type' => 'array',
|
||||||
|
'items' => [
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => [
|
||||||
|
'id' => [
|
||||||
|
'type' => 'integer',
|
||||||
|
'example' => 1,
|
||||||
|
],
|
||||||
|
'name' => [
|
||||||
|
'type' => 'string',
|
||||||
|
'example' => 'Item name',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
])
|
||||||
|
->withSummary('Search for items')
|
||||||
|
->withParameters([
|
||||||
|
new Model\Parameter(
|
||||||
|
'query',
|
||||||
|
'query',
|
||||||
|
'Search query parameter',
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
])
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -11,3 +11,29 @@ validators:
|
||||||
view:
|
view:
|
||||||
name:
|
name:
|
||||||
not_blank: 'The name should not be blank.'
|
not_blank: 'The name should not be blank.'
|
||||||
|
|
||||||
|
hardware:
|
||||||
|
name:
|
||||||
|
not_blank: 'The name should not be blank.'
|
||||||
|
type:
|
||||||
|
not_null: 'The type should not be null.'
|
||||||
|
|
||||||
|
hardware_type:
|
||||||
|
name:
|
||||||
|
not_blank: 'The name should not be blank.'
|
||||||
|
|
||||||
|
image:
|
||||||
|
name:
|
||||||
|
not_blank: 'The name should not be blank.'
|
||||||
|
|
||||||
|
network_settings:
|
||||||
|
ip_address:
|
||||||
|
invalid: 'The IP address "{{ value }}" is not valid.'
|
||||||
|
p2p_time:
|
||||||
|
invalid: 'The P2P time "{{ value }}" is not valid.'
|
||||||
|
mcast_speed:
|
||||||
|
invalid: 'The MCAST speed "{{ value }}" is not valid.'
|
||||||
|
|
||||||
|
operative_system:
|
||||||
|
name:
|
||||||
|
not_blank: 'The name should not be blank.'
|
|
@ -11,3 +11,29 @@ validators:
|
||||||
view:
|
view:
|
||||||
name:
|
name:
|
||||||
not_blank: 'El nombre no debería estar vacío.'
|
not_blank: 'El nombre no debería estar vacío.'
|
||||||
|
|
||||||
|
hardware:
|
||||||
|
name:
|
||||||
|
not_blank: 'El nombre no debería estar vacío.'
|
||||||
|
type:
|
||||||
|
not_null: 'El tipo no debería estar vacío.'
|
||||||
|
|
||||||
|
hardware_type:
|
||||||
|
name:
|
||||||
|
not_blank: 'El nombre no debería estar vacío.'
|
||||||
|
|
||||||
|
image:
|
||||||
|
name:
|
||||||
|
not_blank: 'El nombre no debería estar vacío.'
|
||||||
|
|
||||||
|
network_settings:
|
||||||
|
ip_address:
|
||||||
|
invalid: 'La dirección IP "{{ value }}" no es válida.'
|
||||||
|
p2p_time:
|
||||||
|
invalid: 'El tiempo P2P "{{ value }}" no es válido.'
|
||||||
|
mcast_speed:
|
||||||
|
invalid: 'La velocidad MCAST "{{ value }}" no es válida.'
|
||||||
|
|
||||||
|
operative_system:
|
||||||
|
name:
|
||||||
|
not_blank: 'El nombre no debería estar vacío.'
|
Loading…
Reference in New Issue