diff --git a/config/api_platform/Client.yaml b/config/api_platform/Client.yaml index e69de29..196c658 100644 --- a/config/api_platform/Client.yaml +++ b/config/api_platform/Client.yaml @@ -0,0 +1,33 @@ +resources: + App\Entity\Client: + processor: App\State\Processor\ClientProcessor + input: App\Dto\Input\ClientInput + output: App\Dto\Output\ClientOutput + normalization_context: + groups: ['default', 'client:read'] + denormalization_context: + groups: ['client:write'] + operations: + ApiPlatform\Metadata\GetCollection: + provider: App\State\Provider\ClientProvider + filters: + - 'api_platform.filter.client.order' + - 'api_platform.filter.client.search' + - 'api_platform.filter.client.boolean' + ApiPlatform\Metadata\Get: + provider: App\State\Provider\ClientProvider + ApiPlatform\Metadata\Put: + provider: App\State\Provider\ClientProvider + ApiPlatform\Metadata\Patch: + provider: App\State\Provider\ClientProvider + validationContext: + groups: [ 'client:patch' ] + ApiPlatform\Metadata\Post: ~ + ApiPlatform\Metadata\Delete: ~ + +properties: + App\Entity\Client: + id: + identifier: false + uuid: + identifier: true \ No newline at end of file diff --git a/config/api_platform/Hardware.yaml b/config/api_platform/Hardware.yaml index e69de29..3e81cc6 100644 --- a/config/api_platform/Hardware.yaml +++ b/config/api_platform/Hardware.yaml @@ -0,0 +1,31 @@ +resources: + App\Entity\Hardware: + processor: App\State\Processor\HardwareProcessor + input: App\Dto\Input\HardwareInput + output: App\Dto\Output\HardwareOutput + normalization_context: + groups: ['default', 'hardware:read'] + denormalization_context: + groups: ['hardware:write'] + operations: + ApiPlatform\Metadata\GetCollection: + provider: App\State\Provider\HardwareProvider + filters: + - 'api_platform.filter.hardware.order' + - 'api_platform.filter.hardware.search' + - 'api_platform.filter.hardware.boolean' + ApiPlatform\Metadata\Get: + provider: App\State\Provider\HardwareProvider + ApiPlatform\Metadata\Put: + provider: App\State\Provider\HardwareProvider + ApiPlatform\Metadata\Patch: + provider: App\State\Provider\HardwareProvider + ApiPlatform\Metadata\Post: ~ + ApiPlatform\Metadata\Delete: ~ + +properties: + App\Entity\Hardware: + id: + identifier: false + uuid: + identifier: true \ No newline at end of file diff --git a/config/api_platform/OrganizationalUnit.yaml b/config/api_platform/OrganizationalUnit.yaml index 26fb903..2b7e137 100644 --- a/config/api_platform/OrganizationalUnit.yaml +++ b/config/api_platform/OrganizationalUnit.yaml @@ -1,6 +1,7 @@ resources: App\Entity\OrganizationalUnit: processor: App\State\Processor\OrganizationalUnitProcessor + output: App\Dto\Output\OrganizationalUnitOutput normalization_context: groups: ['default', 'organizational-unit:read'] denormalization_context: @@ -14,6 +15,9 @@ resources: provider: App\State\Provider\OrganizationalUnitProvider ApiPlatform\Metadata\Patch: provider: App\State\Provider\OrganizationalUnitProvider + validationContext: + groups: ['organizational-unit:patch' ] + ApiPlatform\Metadata\Delete: ~ organizational_unit_root: class: ApiPlatform\Metadata\Post diff --git a/config/api_platform/User.yaml b/config/api_platform/User.yaml index efe4597..8f58ad6 100644 --- a/config/api_platform/User.yaml +++ b/config/api_platform/User.yaml @@ -8,7 +8,6 @@ resources: groups: ['default', 'user:read'] denormalization_context: groups: ['user:write'] - operations: ApiPlatform\Metadata\GetCollection: provider: App\State\Provider\UserProvider diff --git a/config/services.yaml b/config/services.yaml index 7e12544..d9649c3 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -36,6 +36,16 @@ services: $itemProvider: '@api_platform.doctrine.orm.state.item_provider' App\State\Provider\OrganizationalUnitProvider: + bind: + $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' + $itemProvider: '@api_platform.doctrine.orm.state.item_provider' + + App\State\Provider\ClientProvider: + bind: + $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' + $itemProvider: '@api_platform.doctrine.orm.state.item_provider' + + App\State\Provider\HardwareProvider: bind: $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' $itemProvider: '@api_platform.doctrine.orm.state.item_provider' \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index b970b39..8b3b902 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -37,6 +37,8 @@ services: - ./:/var/www/html depends_on: - database + environment: + PHP_IDE_CONFIG: serverName=ogcore networks: - ogcore-network diff --git a/docker/Dockerfile-php b/docker/Dockerfile-php index 0ce2698..da6f17e 100644 --- a/docker/Dockerfile-php +++ b/docker/Dockerfile-php @@ -18,3 +18,13 @@ RUN apk add --no-cache bash git jq moreutils openssh rsync yq ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ RUN chmod +x /usr/local/bin/install-php-extensions RUN install-php-extensions sockets + +# Add xdebug +RUN apk add --no-cache --virtual .build-deps $PHPIZE_DEPS +RUN apk add --update linux-headers +RUN pecl install xdebug +RUN docker-php-ext-enable xdebug +RUN apk del -f .build-deps + +COPY ./docker/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini + diff --git a/docker/xdebug.ini b/docker/xdebug.ini index e69de29..f717c09 100644 --- a/docker/xdebug.ini +++ b/docker/xdebug.ini @@ -0,0 +1,4 @@ +xdebug.mode=debug +xdebug.start_with_request=yes +xdebug.client_host=172.17.0.1/ +xdebug.client_port=9003 \ No newline at end of file diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php index f2b8986..76fb475 100644 --- a/src/DataFixtures/AppFixtures.php +++ b/src/DataFixtures/AppFixtures.php @@ -5,6 +5,7 @@ namespace App\DataFixtures; use App\Entity\OrganizationalUnit; use App\Factory\OrganizationalUnitFactory; use App\Factory\UserFactory; +use App\Model\OrganizationalUnitTypes; use App\Model\UserGroupPermissions; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; @@ -19,16 +20,18 @@ class AppFixtures extends Fixture public function load(ObjectManager $manager): void { UserFactory::createOne(['username' => self::ADMIN_USER, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); - $rootUnit = OrganizationalUnitFactory::createOne(['name' => 'Centro de Computación', 'parent' => null]); + $rootUnit = OrganizationalUnitFactory::createOne(['name' => 'Centro de Computación', 'parent' => null, 'type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]); $roomUnit = OrganizationalUnitFactory::createOne([ 'name' => 'Aula 1', - 'parent' => $rootUnit + 'parent' => $rootUnit, + 'type' => OrganizationalUnitTypes::CLASSROOMS_GROUP ]); OrganizationalUnitFactory::createOne([ 'name' => 'Aula 2', - 'parent' => $roomUnit + 'parent' => $roomUnit, + 'type' => OrganizationalUnitTypes::CLASSROOM ]); } } diff --git a/src/Dto/Input/ClientInput.php b/src/Dto/Input/ClientInput.php index c3af412..f929311 100644 --- a/src/Dto/Input/ClientInput.php +++ b/src/Dto/Input/ClientInput.php @@ -2,7 +2,78 @@ namespace App\Dto\Input; -class ClientInput -{ +use ApiPlatform\Metadata\ApiProperty; +use App\Dto\Output\OrganizationalUnitOutput; +use App\Entity\Client; +use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Validator\Constraints as Assert; +final class ClientInput +{ + #[Assert\NotBlank] + #[Groups(['client:write'])] + #[ApiProperty(description: 'The name of the client', example: "Client 1")] + public ?string $name = null; + + #[Groups(['client:write'])] + #[ApiProperty(description: 'The serial number of the client', example: "123456")] + public ?string $serialNumber = null; + + #[Groups(['client:write'])] + #[ApiProperty(description: 'The network interface of the client', example: "eth0")] + public ?string $netiface = null; + + #[Groups(['client:write'])] + #[ApiProperty(description: 'The network driver of the client', example: "e1000e")] + public ?string $netDriver = null; + + #[Groups(['client:write'])] + #[ApiProperty(description: 'The MAC address of the client', example: "00:11:22:33:44:55")] + public ?string $mac = null; + + #[Groups(['client:write'])] + #[ApiProperty(description: 'The IP address of the client', example: "127.0.0.1")] + public ?string $ip = null; + + #[Groups(['client:write'])] + public ?string $status = null; + + #[Assert\NotNull] + #[Groups(['client:write', 'client:patch'])] + #[ApiProperty(description: 'The organizational unit of the client')] + public ?OrganizationalUnitOutput $organizationalUnit = null; + + public function __construct(?Client $client = null) + { + if (!$client) { + return; + } + + $this->name = $client->getName(); + $this->serialNumber = $client->getSerialNumber(); + $this->netiface = $client->getNetiface(); + $this->organizationalUnit = new OrganizationalUnitOutput($client->getOrganizationalUnit()); + $this->netDriver = $client->getNetDriver(); + $this->mac = $client->getMac(); + $this->ip = $client->getIp(); + $this->status = $client->getStatus(); + } + + public function createOrUpdateEntity(?Client $client = null): Client + { + if (!$client) { + $client = new Client(); + } + + $client->setName($this->name); + $client->setSerialNumber($this->serialNumber); + $client->setNetiface($this->netiface); + $client->setOrganizationalUnit($this->organizationalUnit->getEntity()); + $client->setNetDriver($this->netDriver); + $client->setMac($this->mac); + $client->setIp($this->ip); + $client->setStatus($this->status); + + return $client; + } } \ No newline at end of file diff --git a/src/Dto/Input/HardwareInput.php b/src/Dto/Input/HardwareInput.php index d3134fd..f46117a 100644 --- a/src/Dto/Input/HardwareInput.php +++ b/src/Dto/Input/HardwareInput.php @@ -2,7 +2,48 @@ namespace App\Dto\Input; -class HardwareInput -{ +use ApiPlatform\Metadata\ApiProperty; +use App\Entity\Hardware; +use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Validator\Constraints as Assert; +final class HardwareInput +{ + #[Assert\NotBlank] + #[Groups(['hardware:write'])] + #[ApiProperty(description: 'The name of the hardware', example: "Hardware 1")] + public ?string $name = null; + + #[Groups(['hardware:write'])] + #[ApiProperty(description: 'The description of the hardware', example: "Hardware 1 description")] + public ?string $description = null; + + #[Groups(['hardware:write'])] + #[ApiProperty(description: 'The type of the hardware', example: "Server")] + public ?string $type = null; + + + public function __construct(?Hardware $hardware = null) + { + if (!$hardware) { + return; + } + + $this->name = $hardware->getName(); + $this->description = $hardware->getDescription(); + $this->type = $hardware->getType(); + } + + public function createOrUpdateEntity(?Hardware $hardware = null): Hardware + { + if (!$hardware) { + $hardware = new Hardware(); + } + + $hardware->setName($this->name); + $hardware->setDescription($this->description); + $hardware->setType($this->type); + + return $hardware; + } } \ No newline at end of file diff --git a/src/Dto/Input/OrganizationalUnitClassroomGroupInput.php b/src/Dto/Input/OrganizationalUnitClassroomGroupInput.php index 3d1aee5..8b8f33f 100644 --- a/src/Dto/Input/OrganizationalUnitClassroomGroupInput.php +++ b/src/Dto/Input/OrganizationalUnitClassroomGroupInput.php @@ -31,7 +31,7 @@ final class OrganizationalUnitClassroomGroupInput } $this->name = $organizationalUnit->getName(); - $this->parent = $organizationalUnit->getParent(); + $this->parent = new OrganizationalUnitOutput($organizationalUnit->getParent()); $this->description = $organizationalUnit->getDescription(); $this->comments = $organizationalUnit->getComments(); } diff --git a/src/Dto/Input/OrganizationalUnitClassroomInput.php b/src/Dto/Input/OrganizationalUnitClassroomInput.php index 1bdf977..7603906 100644 --- a/src/Dto/Input/OrganizationalUnitClassroomInput.php +++ b/src/Dto/Input/OrganizationalUnitClassroomInput.php @@ -3,8 +3,10 @@ namespace App\Dto\Input; use App\Dto\Output\OrganizationalUnitOutput; +use App\Entity\NetworkSettings; use App\Entity\OrganizationalUnit; use App\Model\OrganizationalUnitTypes; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Constraints as Assert; @@ -15,7 +17,7 @@ final class OrganizationalUnitClassroomInput public ?string $name = null; #[Assert\NotNull] - #[Groups(['organizational-unit:write'])] + #[Groups(['organizational-unit:write', 'organizational-unit:patch'])] public ?OrganizationalUnitOutput $parent = null; #[Groups(['organizational-unit:write'])] @@ -36,6 +38,40 @@ final class OrganizationalUnitClassroomInput #[Groups(['organizational-unit:write'])] public ?int $capacity = null; + #[Groups(['organizational-unit:write'])] + public ?string $proxy = null; + + #[Groups(['organizational-unit:write'])] + public ?string $dns = null; + + #[Groups(['organizational-unit:write'])] + public ?string $netmask = null; + + #[Groups(['organizational-unit:write'])] + public ?string $router = null; + + #[Groups(['organizational-unit:write'])] + public ?string $ntp = null; + + #[Groups(['organizational-unit:write'])] + public ?string $p2pMode = null; + + #[Groups(['organizational-unit:write'])] + public ?int $p2pTime = null; + + #[Assert\Ip] + #[Groups(['organizational-unit:write'])] + public ?string $mcastIp = null; + + #[Groups(['organizational-unit:write'])] + public ?int $mcastSpeed = null; + + #[Groups(['organizational-unit:write'])] + public ?int $mcastPort = null; + + #[Groups(['organizational-unit:write'])] + public ?string $mcastMode = null; + public function __construct(?OrganizationalUnit $organizationalUnit = null) { if (!$organizationalUnit) { @@ -43,16 +79,30 @@ final class OrganizationalUnitClassroomInput } $this->name = $organizationalUnit->getName(); - $this->parent = $organizationalUnit->getParent(); + $this->parent = new OrganizationalUnitOutput($organizationalUnit->getParent()); $this->description = $organizationalUnit->getDescription(); $this->comments = $organizationalUnit->getComments(); $this->location = $organizationalUnit->getLocation(); $this->projector = $organizationalUnit->isProjector(); $this->board = $organizationalUnit->isBoard(); $this->capacity = $organizationalUnit->getCapacity(); + $this->proxy = $organizationalUnit->getNetworkSettings()->getProxy(); + $this->dns = $organizationalUnit->getNetworkSettings()->getDns(); + $this->netmask = $organizationalUnit->getNetworkSettings()->getNetmask(); + $this->router = $organizationalUnit->getNetworkSettings()->getRouter(); + $this->ntp = $organizationalUnit->getNetworkSettings()->getNtp(); + $this->p2pMode = $organizationalUnit->getNetworkSettings()->getP2pMode(); + $this->p2pTime = $organizationalUnit->getNetworkSettings()->getP2pTime(); + $this->mcastIp = $organizationalUnit->getNetworkSettings()->getMcastIp(); + $this->mcastSpeed = $organizationalUnit->getNetworkSettings()->getMcastSpeed(); + $this->mcastPort = $organizationalUnit->getNetworkSettings()->getMcastPort(); + $this->mcastMode = $organizationalUnit->getNetworkSettings()->getMcastMode(); } - public function createOrUpdateEntity(?OrganizationalUnit $organizationalUnit = null): OrganizationalUnit + public function createOrUpdateEntity( + ?OrganizationalUnit $organizationalUnit = null, + ?EntityManagerInterface $entityManager = null + ): OrganizationalUnit { if (!$organizationalUnit) { $organizationalUnit = new OrganizationalUnit(); @@ -68,6 +118,22 @@ final class OrganizationalUnitClassroomInput $organizationalUnit->setBoard($this->board); $organizationalUnit->setCapacity($this->capacity); + $networkSettings = new NetworkSettings(); + $networkSettings->setProxy($this->proxy); + $networkSettings->setDns($this->dns); + $networkSettings->setNetmask($this->netmask); + $networkSettings->setRouter($this->router); + $networkSettings->setNtp($this->ntp); + $networkSettings->setP2pMode($this->p2pMode); + $networkSettings->setP2pTime($this->p2pTime); + $networkSettings->setMcastIp($this->mcastIp); + $networkSettings->setMcastSpeed($this->mcastSpeed); + $networkSettings->setMcastPort($this->mcastPort); + $networkSettings->setMcastMode($this->mcastMode); + $entityManager->persist($networkSettings); + + $organizationalUnit->setNetworkSettings($networkSettings); + return $organizationalUnit; } } \ No newline at end of file diff --git a/src/Dto/Input/OrganizationalUnitClientGroupInput.php b/src/Dto/Input/OrganizationalUnitClientGroupInput.php index 9ef1742..bbc9458 100644 --- a/src/Dto/Input/OrganizationalUnitClientGroupInput.php +++ b/src/Dto/Input/OrganizationalUnitClientGroupInput.php @@ -31,7 +31,7 @@ final class OrganizationalUnitClientGroupInput } $this->name = $organizationalUnit->getName(); - $this->parent = $organizationalUnit->getParent(); + $this->parent = new OrganizationalUnitOutput($organizationalUnit->getParent()); $this->description = $organizationalUnit->getDescription(); $this->comments = $organizationalUnit->getComments(); } diff --git a/src/Dto/Output/ClientOutput.php b/src/Dto/Output/ClientOutput.php index 3bcaf3a..fd48afd 100644 --- a/src/Dto/Output/ClientOutput.php +++ b/src/Dto/Output/ClientOutput.php @@ -2,7 +2,41 @@ namespace App\Dto\Output; -class ClientOutput -{ +use ApiPlatform\Metadata\Get; +use App\Entity\Client; +use App\Entity\OrganizationalUnit; +use Symfony\Component\Serializer\Annotation\Groups; +#[Get(shortName: 'Client')] +final class ClientOutput extends AbstractOutput +{ + #[Groups(['client:read'])] + public string $name; + + #[Groups(['client:read'])] + public ?string $serialNumber = ''; + + #[Groups(['client:read'])] + public ?string $netiface = ''; + + #[Groups(['client:read'])] + public ?OrganizationalUnit $organizationalUnit = null; + + #[Groups(['client:read'])] + public \DateTime $createAt; + + #[Groups(['client:read'])] + public ?string $createBy = null; + + public function __construct(Client $client) + { + parent::__construct($client); + + $this->name = $client->getName(); + $this->serialNumber = $client->getSerialNumber(); + $this->netiface = $client->getNetiface(); + $this->organizationalUnit = $client->getOrganizationalUnit(); + $this->createAt = $client->getCreatedAt(); + $this->createBy = $client->getCreatedBy(); + } } \ No newline at end of file diff --git a/src/Dto/Output/HardwareOutput.php b/src/Dto/Output/HardwareOutput.php index e1603db..a0ebf9d 100644 --- a/src/Dto/Output/HardwareOutput.php +++ b/src/Dto/Output/HardwareOutput.php @@ -2,7 +2,36 @@ namespace App\Dto\Output; -class HardwareOutput -{ +use ApiPlatform\Metadata\Get; +use App\Entity\Hardware; +use Symfony\Component\Serializer\Annotation\Groups; +#[Get(shortName: 'Hardware')] +final class HardwareOutput extends AbstractOutput +{ + #[Groups(['hardware:read'])] + public string $name; + + #[Groups(['hardware:read'])] + public string $description; + + #[Groups(['hardware:read'])] + public string $type; + + #[Groups(['hardware:read'])] + public \DateTime $createAt; + + #[Groups(['hardware:read'])] + public ?string $createBy = null; + + public function __construct(Hardware $hardware) + { + parent::__construct($hardware); + + $this->name = $hardware->getName(); + $this->description = $hardware->getDescription(); + $this->type = $hardware->getType(); + $this->createAt = $hardware->getCreatedAt(); + $this->createBy = $hardware->getCreatedBy(); + } } \ No newline at end of file diff --git a/src/Dto/Output/NetworkSettingsOutput.php b/src/Dto/Output/NetworkSettingsOutput.php index c5ae79a..082d26b 100644 --- a/src/Dto/Output/NetworkSettingsOutput.php +++ b/src/Dto/Output/NetworkSettingsOutput.php @@ -2,7 +2,64 @@ namespace App\Dto\Output; -class NetworkSettingsOutput -{ +use App\Entity\NetworkSettings; +use Symfony\Component\Serializer\Annotation\Groups; +final class NetworkSettingsOutput +{ + #[Groups(['organizational-unit:read'])] + public ?string $proxy = null; + + #[Groups(['organizational-unit:read'])] + public ?string $dns = null; + + #[Groups(['organizational-unit:read'])] + public ?string $netmask = null; + + #[Groups(['organizational-unit:read'])] + public ?string $router = null; + + #[Groups(['organizational-unit:read'])] + public ?string $ntp = null; + + #[Groups(['organizational-unit:read'])] + public ?string $p2pMode = null; + + #[Groups(['organizational-unit:read'])] + public ?int $p2pTime = null; + + #[Groups(['organizational-unit:read'])] + public ?string $mcastIp = null; + + #[Groups(['organizational-unit:read'])] + public ?int $mcastSpeed = null; + + #[Groups(['organizational-unit:read'])] + public ?int $mcastPort = null; + + #[Groups(['organizational-unit:read'])] + public ?string $mcastMode = null; + + #[Groups(['organizational-unit:read'])] + public \DateTime $createAt; + + #[Groups(['organizational-unit:read'])] + public ?string $createBy = null; + + public function __construct(NetworkSettings $networkSettings) + { + $this->proxy = $networkSettings->getProxy(); + $this->dns = $networkSettings->getDns(); + $this->netmask = $networkSettings->getNetmask(); + $this->router = $networkSettings->getRouter(); + $this->ntp = $networkSettings->getNtp(); + $this->p2pMode = $networkSettings->getP2pMode(); + $this->p2pTime = $networkSettings->getP2pTime(); + $this->mcastIp = $networkSettings->getMcastIp(); + $this->mcastSpeed = $networkSettings->getMcastSpeed(); + $this->mcastPort = $networkSettings->getMcastPort(); + $this->mcastMode = $networkSettings->getMcastMode(); + $this->createAt = $networkSettings->getCreatedAt(); + $this->createBy = $networkSettings->getCreatedBy(); + } } \ No newline at end of file diff --git a/src/Dto/Output/OrganizationalUnitOutput.php b/src/Dto/Output/OrganizationalUnitOutput.php index 923b2f0..2ab65e5 100644 --- a/src/Dto/Output/OrganizationalUnitOutput.php +++ b/src/Dto/Output/OrganizationalUnitOutput.php @@ -2,6 +2,7 @@ namespace App\Dto\Output; +use ApiPlatform\Metadata\ApiProperty; use ApiPlatform\Metadata\Get; use App\Entity\OrganizationalUnit; use Symfony\Component\Serializer\Annotation\Groups; @@ -16,16 +17,23 @@ final class OrganizationalUnitOutput extends AbstractOutput public string $type; #[Groups(['organizational-unit:read'])] - public ?OrganizationalUnit $parent = null; + public ?self $parent = null; #[Groups(['organizational-unit:read'])] public string $path; #[Groups(['organizational-unit:read'])] - public \DateTime $createAt; + public ?NetworkSettingsOutput $networkSettings = null; + + #[Groups(['user:read'])] + public array $clients = []; #[Groups(['organizational-unit:read'])] - public ?string $createBy = null; + public \DateTime $createdAt; + + #[Groups(['organizational-unit:read'])] + public ?string $createdBy = null; + public function __construct(OrganizationalUnit $organizationalUnit) { @@ -33,9 +41,15 @@ final class OrganizationalUnitOutput extends AbstractOutput $this->name = $organizationalUnit->getName(); $this->type = $organizationalUnit->getType(); - $this->parent = $organizationalUnit->getParent(); + $this->networkSettings = $organizationalUnit->getNetworkSettings() ? new NetworkSettingsOutput($organizationalUnit->getNetworkSettings()) : null; + $this->clients = $organizationalUnit->getClients()->toArray(); + + if ($organizationalUnit->getParent()) { + $this->parent = new self($organizationalUnit->getParent()); + } + $this->path = $organizationalUnit->getPath(); - $this->createAt = $organizationalUnit->getCreatedAt(); - $this->createBy = $organizationalUnit->getCreatedBy(); + $this->createdAt = $organizationalUnit->getCreatedAt(); + $this->createdBy = $organizationalUnit->getCreatedBy(); } } \ No newline at end of file diff --git a/src/State/Processor/ClientProcessor.php b/src/State/Processor/ClientProcessor.php index 4f6e068..c3deba4 100644 --- a/src/State/Processor/ClientProcessor.php +++ b/src/State/Processor/ClientProcessor.php @@ -2,7 +2,68 @@ namespace App\State\Processor; -class ClientProcessor -{ +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Operation; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; +use ApiPlatform\Metadata\Put; +use ApiPlatform\State\ProcessorInterface; +use ApiPlatform\Validator\ValidatorInterface; +use App\Dto\Input\ClientInput; +use App\Dto\Output\ClientOutput; +use App\Dto\Output\UserGroupOutput; +use App\Repository\ClientRepository; -} \ No newline at end of file +class ClientProcessor implements ProcessorInterface +{ + public function __construct( + private readonly ClientRepository $clientRepository, + private readonly ValidatorInterface $validator + ) + { + } + + /** + * @throws \Exception + */ + public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): ClientOutput + { + switch ($operation){ + case $operation instanceof Post: + case $operation instanceof Put: + case $operation instanceof Patch: + return $this->processCreateOrUpdate($data, $operation, $uriVariables, $context); + case $operation instanceof Delete: + return $this->processDelete($data, $operation, $uriVariables, $context); + } + } + + /** + * @throws \Exception + */ + private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): ClientOutput + { + if (!($data instanceof ClientInput)) { + throw new \Exception(sprintf('data is not instance of %s', ClientInput::class)); + } + + $entity = null; + if (isset($uriVariables['uuid'])) { + $entity = $this->clientRepository->findOneByUuid($uriVariables['uuid']); + } + + $userGroup = $data->createOrUpdateEntity($entity); + $this->validator->validate($userGroup); + $this->clientRepository->save($userGroup); + + return new ClientOutput($userGroup); + } + + private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null + { + $user = $this->clientRepository->findOneByUuid($uriVariables['uuid']); + $this->clientRepository->delete($user); + + return null; + } +} diff --git a/src/State/Processor/HardwareProcessor.php b/src/State/Processor/HardwareProcessor.php index 6831264..c396d3e 100644 --- a/src/State/Processor/HardwareProcessor.php +++ b/src/State/Processor/HardwareProcessor.php @@ -2,7 +2,69 @@ namespace App\State\Processor; -class HardwareProcessor -{ +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Operation; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; +use ApiPlatform\Metadata\Put; +use ApiPlatform\State\ProcessorInterface; +use ApiPlatform\Validator\ValidatorInterface; +use App\Dto\Input\ClientInput; +use App\Dto\Input\HardwareInput; +use App\Dto\Output\ClientOutput; +use App\Dto\Output\HardwareOutput; +use App\Repository\HardwareRepository; -} \ No newline at end of file +class HardwareProcessor implements ProcessorInterface +{ + public function __construct( + private readonly HardwareRepository $hardwareRepository, + private readonly ValidatorInterface $validator + ) + { + } + + /** + * @throws \Exception + */ + public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): HardwareOutput + { + switch ($operation){ + case $operation instanceof Post: + case $operation instanceof Put: + case $operation instanceof Patch: + return $this->processCreateOrUpdate($data, $operation, $uriVariables, $context); + case $operation instanceof Delete: + return $this->processDelete($data, $operation, $uriVariables, $context); + } + } + + /** + * @throws \Exception + */ + private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): HardwareOutput + { + if (!($data instanceof ClientInput)) { + throw new \Exception(sprintf('data is not instance of %s', HardwareInput::class)); + } + + $entity = null; + if (isset($uriVariables['uuid'])) { + $entity = $this->hardwareRepository->findOneByUuid($uriVariables['uuid']); + } + + $userGroup = $data->createOrUpdateEntity($entity); + $this->validator->validate($userGroup); + $this->hardwareRepository->save($userGroup); + + return new HardwareOutput($userGroup); + } + + private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null + { + $user = $this->hardwareRepository->findOneByUuid($uriVariables['uuid']); + $this->hardwareRepository->delete($user); + + return null; + } +} diff --git a/src/State/Processor/OrganizationalUnitProcessor.php b/src/State/Processor/OrganizationalUnitProcessor.php index 5bd3c99..f307079 100644 --- a/src/State/Processor/OrganizationalUnitProcessor.php +++ b/src/State/Processor/OrganizationalUnitProcessor.php @@ -15,12 +15,14 @@ use App\Dto\Input\OrganizationalUnitClientGroupInput; use App\Dto\Input\OrganizationalUnitRootInput; use App\Dto\Output\OrganizationalUnitOutput; use App\Repository\OrganizationalUnitRepository; +use Doctrine\ORM\EntityManagerInterface; class OrganizationalUnitProcessor implements ProcessorInterface { public function __construct( private readonly OrganizationalUnitRepository $organizationalUnitRepository, - private readonly ValidatorInterface $validator + private readonly ValidatorInterface $validator, + private readonly EntityManagerInterface $entityManager ) { } @@ -62,7 +64,7 @@ class OrganizationalUnitProcessor implements ProcessorInterface $entity = $this->organizationalUnitRepository->findOneByUuid($uriVariables['uuid']); } - $organizationalUnit = $data->createOrUpdateEntity($entity); + $organizationalUnit = $data->createOrUpdateEntity($entity, $this->entityManager); $this->validator->validate($organizationalUnit); $this->organizationalUnitRepository->save($organizationalUnit); diff --git a/src/State/Provider/ClientProvider.php b/src/State/Provider/ClientProvider.php index a468d9b..d398a0f 100644 --- a/src/State/Provider/ClientProvider.php +++ b/src/State/Provider/ClientProvider.php @@ -2,7 +2,70 @@ namespace App\State\Provider; -class ClientProvider -{ +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Operation; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Put; +use ApiPlatform\State\Pagination\TraversablePaginator; +use ApiPlatform\State\ProviderInterface; +use App\Dto\Input\ClientInput; +use App\Dto\Output\ClientOutput; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -} \ No newline at end of file +class ClientProvider implements ProviderInterface +{ + public function __construct( + private readonly ProviderInterface $collectionProvider, + private readonly ProviderInterface $itemProvider + ) + { + } + + public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + switch ($operation){ + case $operation instanceof GetCollection: + return $this->provideCollection($operation, $uriVariables, $context); + case $operation instanceof Patch: + case $operation instanceof Put: + return $this->provideInput($operation, $uriVariables, $context); + case $operation instanceof Get: + return $this->provideItem($operation, $uriVariables, $context); + } + } + + private function provideCollection(Operation $operation, array $uriVariables = [], array $context = []): object + { + $paginator = $this->collectionProvider->provide($operation, $uriVariables, $context); + + $items = new \ArrayObject(); + foreach ($paginator->getIterator() as $item){ + $items[] = new ClientOutput($item); + } + + return new TraversablePaginator($items, $paginator->getCurrentPage(), $paginator->getItemsPerPage(), $paginator->getTotalItems()); + } + + public function provideItem(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + if (!$item) { + throw new NotFoundHttpException('Client not found'); + } + + return new ClientOutput($item); + } + + public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + if (isset($uriVariables['uuid'])) { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + return $item !== null ? new ClientInput($item) : null; + } + + return new ClientInput(); + } +} diff --git a/src/State/Provider/HardwareProvider.php b/src/State/Provider/HardwareProvider.php index abc07ba..d62dd29 100644 --- a/src/State/Provider/HardwareProvider.php +++ b/src/State/Provider/HardwareProvider.php @@ -2,7 +2,72 @@ namespace App\State\Provider; -class HardwareProvider -{ +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Operation; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Put; +use ApiPlatform\State\Pagination\TraversablePaginator; +use ApiPlatform\State\ProviderInterface; +use App\Dto\Input\ClientInput; +use App\Dto\Input\HardwareInput; +use App\Dto\Output\ClientOutput; +use App\Dto\Output\HardwareOutput; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -} \ No newline at end of file +class HardwareProvider implements ProviderInterface +{ + public function __construct( + private readonly ProviderInterface $collectionProvider, + private readonly ProviderInterface $itemProvider + ) + { + } + + public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + switch ($operation){ + case $operation instanceof GetCollection: + return $this->provideCollection($operation, $uriVariables, $context); + case $operation instanceof Patch: + case $operation instanceof Put: + return $this->provideInput($operation, $uriVariables, $context); + case $operation instanceof Get: + return $this->provideItem($operation, $uriVariables, $context); + } + } + + private function provideCollection(Operation $operation, array $uriVariables = [], array $context = []): object + { + $paginator = $this->collectionProvider->provide($operation, $uriVariables, $context); + + $items = new \ArrayObject(); + foreach ($paginator->getIterator() as $item){ + $items[] = new HardwareOutput($item); + } + + return new TraversablePaginator($items, $paginator->getCurrentPage(), $paginator->getItemsPerPage(), $paginator->getTotalItems()); + } + + public function provideItem(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + if (!$item) { + throw new NotFoundHttpException('Hardware not found'); + } + + return new HardwareOutput($item); + } + + public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + if (isset($uriVariables['uuid'])) { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + return $item !== null ? new ClientInput($item) : null; + } + + return new HardwareInput(); + } +} diff --git a/src/State/Provider/OrganizationalUnitProvider.php b/src/State/Provider/OrganizationalUnitProvider.php index 83d5735..be6031d 100644 --- a/src/State/Provider/OrganizationalUnitProvider.php +++ b/src/State/Provider/OrganizationalUnitProvider.php @@ -9,8 +9,14 @@ use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Put; use ApiPlatform\State\Pagination\TraversablePaginator; use ApiPlatform\State\ProviderInterface; +use App\Dto\Input\OrganizationalUnitClassroomGroupInput; +use App\Dto\Input\OrganizationalUnitClassroomInput; +use App\Dto\Input\OrganizationalUnitClientGroupInput; +use App\Dto\Input\OrganizationalUnitRootInput; use App\Dto\Input\UserGroupInput; use App\Dto\Output\OrganizationalUnitOutput; +use App\Entity\OrganizationalUnit; +use App\Model\OrganizationalUnitTypes; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class OrganizationalUnitProvider implements ProviderInterface @@ -60,12 +66,28 @@ class OrganizationalUnitProvider implements ProviderInterface public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null { + $input = null; + if (isset($uriVariables['uuid'])) { $item = $this->itemProvider->provide($operation, $uriVariables, $context); - return $item !== null ? new UserGroupInput($item) : null; - } + if ( $item !== null ) { + switch ($item->getType()) { + case OrganizationalUnitTypes::ORGANIZATIONAL_UNIT: + $input = new OrganizationalUnitRootInput($item); + break; + case OrganizationalUnitTypes::CLASSROOMS_GROUP: + $input = new OrganizationalUnitClassroomGroupInput($item); + break; + case OrganizationalUnitTypes::CLIENTS_GROUP: + $input = new OrganizationalUnitClientGroupInput($item); + break; + case OrganizationalUnitTypes::CLASSROOM; + $input = new OrganizationalUnitClassroomInput($item); + } + } - return new UserGroupInput(); + return $input; + } } }