feat: add API Platform

This commit is contained in:
Maël Gangloff 2024-07-17 00:19:27 +02:00
parent 16610205b6
commit 36a76f2876
No known key found for this signature in database
GPG Key ID: 11FDC81C24A7F629
18 changed files with 489 additions and 3 deletions

4
.env
View File

@ -39,3 +39,7 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
###> symfony/mailer ### ###> symfony/mailer ###
# MAILER_DSN=null://null # MAILER_DSN=null://null
###< symfony/mailer ### ###< symfony/mailer ###
###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
###< nelmio/cors-bundle ###

View File

@ -7,11 +7,13 @@
"php": ">=8.2", "php": ">=8.2",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"api-platform/core": "^3.3",
"doctrine/dbal": "^3", "doctrine/dbal": "^3",
"doctrine/doctrine-bundle": "^2.12", "doctrine/doctrine-bundle": "^2.12",
"doctrine/doctrine-migrations-bundle": "^3.3", "doctrine/doctrine-migrations-bundle": "^3.3",
"doctrine/orm": "^3.2", "doctrine/orm": "^3.2",
"eluceo/ical": "^2.14", "eluceo/ical": "^2.14",
"nelmio/cors-bundle": "^2.5",
"phpdocumentor/reflection-docblock": "^5.4", "phpdocumentor/reflection-docblock": "^5.4",
"phpstan/phpdoc-parser": "^1.29", "phpstan/phpdoc-parser": "^1.29",
"protonlabs/vobject": "^4.31", "protonlabs/vobject": "^4.31",

308
composer.lock generated
View File

@ -4,8 +4,196 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "139867d77c0de3a6d8dfd5df9210b52b", "content-hash": "cad4d9a9dfcfdf50a0cf2e374b7b666c",
"packages": [ "packages": [
{
"name": "api-platform/core",
"version": "v3.3.9",
"source": {
"type": "git",
"url": "https://github.com/api-platform/core.git",
"reference": "53e6ce7c2080820cc88713c27ed318086ace6149"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/api-platform/core/zipball/53e6ce7c2080820cc88713c27ed318086ace6149",
"reference": "53e6ce7c2080820cc88713c27ed318086ace6149",
"shasum": ""
},
"require": {
"doctrine/inflector": "^1.0 || ^2.0",
"php": ">=8.1",
"psr/cache": "^1.0 || ^2.0 || ^3.0",
"psr/container": "^1.0 || ^2.0",
"symfony/deprecation-contracts": "^3.1",
"symfony/http-foundation": "^6.4 || ^7.0",
"symfony/http-kernel": "^6.4 || ^7.0",
"symfony/property-access": "^6.4 || ^7.0",
"symfony/property-info": "^6.4 || ^7.0",
"symfony/serializer": "^6.4 || ^7.0",
"symfony/translation-contracts": "^3.3",
"symfony/web-link": "^6.4 || ^7.0",
"willdurand/negotiation": "^3.0"
},
"conflict": {
"doctrine/common": "<3.2.2",
"doctrine/dbal": "<2.10",
"doctrine/mongodb-odm": "<2.4",
"doctrine/orm": "<2.14.0",
"doctrine/persistence": "<1.3",
"elasticsearch/elasticsearch": ">=8.0,<8.4",
"phpspec/prophecy": "<1.15",
"phpunit/phpunit": "<9.5",
"symfony/framework-bundle": "6.4.6 || 7.0.6",
"symfony/var-exporter": "<6.1.1"
},
"require-dev": {
"behat/behat": "^3.11",
"behat/mink": "^1.9",
"doctrine/cache": "^1.11 || ^2.1",
"doctrine/common": "^3.2.2",
"doctrine/dbal": "^3.4.0",
"doctrine/doctrine-bundle": "^1.12 || ^2.0",
"doctrine/mongodb-odm": "^2.2",
"doctrine/mongodb-odm-bundle": "^4.0 || ^5.0",
"doctrine/orm": "^2.14 || ^3.0",
"elasticsearch/elasticsearch": "^7.11 || ^8.4",
"friends-of-behat/mink-browserkit-driver": "^1.3.1",
"friends-of-behat/mink-extension": "^2.2",
"friends-of-behat/symfony-extension": "^2.1",
"guzzlehttp/guzzle": "^6.0 || ^7.0",
"jangregor/phpstan-prophecy": "^1.0",
"justinrainbow/json-schema": "^5.2.1",
"phpspec/prophecy-phpunit": "^2.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpdoc-parser": "^1.13",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-doctrine": "^1.0",
"phpstan/phpstan-phpunit": "^1.0",
"phpstan/phpstan-symfony": "^1.0",
"phpunit/phpunit": "^9.6",
"psr/log": "^1.0 || ^2.0 || ^3.0",
"ramsey/uuid": "^3.9.7 || ^4.0",
"ramsey/uuid-doctrine": "^1.4 || ^2.0",
"sebastian/comparator": "<5.0",
"soyuka/contexts": "v3.3.9",
"soyuka/pmu": "^0.0.2",
"soyuka/stubs-mongodb": "^1.0",
"symfony/asset": "^6.4 || ^7.0",
"symfony/browser-kit": "^6.4 || ^7.0",
"symfony/cache": "^6.4 || ^7.0",
"symfony/config": "^6.4 || ^7.0",
"symfony/console": "^6.4 || ^7.0",
"symfony/css-selector": "^6.4 || ^7.0",
"symfony/dependency-injection": "^6.4 || ^7.0.12",
"symfony/doctrine-bridge": "^6.4 || ^7.0",
"symfony/dom-crawler": "^6.4 || ^7.0",
"symfony/error-handler": "^6.4 || ^7.0",
"symfony/event-dispatcher": "^6.4 || ^7.0",
"symfony/expression-language": "^6.4 || ^7.0",
"symfony/finder": "^6.4 || ^7.0",
"symfony/form": "^6.4 || ^7.0",
"symfony/framework-bundle": "^6.4 || ^7.0",
"symfony/http-client": "^6.4 || ^7.0",
"symfony/intl": "^6.4 || ^7.0",
"symfony/maker-bundle": "^1.24",
"symfony/mercure-bundle": "*",
"symfony/messenger": "^6.4 || ^7.0",
"symfony/phpunit-bridge": "^6.4.1 || ^7.0",
"symfony/routing": "^6.4 || ^7.0",
"symfony/security-bundle": "^6.4 || ^7.0",
"symfony/security-core": "^6.4 || ^7.0",
"symfony/stopwatch": "^6.4 || ^7.0",
"symfony/twig-bundle": "^6.4 || ^7.0",
"symfony/uid": "^6.4 || ^7.0",
"symfony/validator": "^6.4 || ^7.0",
"symfony/web-profiler-bundle": "^6.4 || ^7.0",
"symfony/yaml": "^6.4 || ^7.0",
"twig/twig": "^1.42.3 || ^2.12 || ^3.0",
"webonyx/graphql-php": "^14.0 || ^15.0"
},
"suggest": {
"doctrine/mongodb-odm-bundle": "To support MongoDB. Only versions 4.0 and later are supported.",
"elasticsearch/elasticsearch": "To support Elasticsearch.",
"ocramius/package-versions": "To display the API Platform's version in the debug bar.",
"phpstan/phpdoc-parser": "To support extracting metadata from PHPDoc.",
"psr/cache-implementation": "To use metadata caching.",
"ramsey/uuid": "To support Ramsey's UUID identifiers.",
"symfony/cache": "To have metadata caching when using Symfony integration.",
"symfony/config": "To load XML configuration files.",
"symfony/expression-language": "To use authorization features.",
"symfony/http-client": "To use the HTTP cache invalidation system.",
"symfony/messenger": "To support messenger integration.",
"symfony/security": "To use authorization features.",
"symfony/twig-bundle": "To use the Swagger UI integration.",
"symfony/uid": "To support Symfony UUID/ULID identifiers.",
"symfony/web-profiler-bundle": "To use the data collector.",
"webonyx/graphql-php": "To support GraphQL."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.3.x-dev"
},
"symfony": {
"require": "^6.4 || ^7.0"
},
"projects": [
"api-platform/doctrine-common",
"api-platform/doctrine-orm",
"api-platform/doctrine-odm",
"api-platform/metadata",
"api-platform/json-schema",
"api-platform/elasticsearch",
"api-platform/jsonld",
"api-platform/hydra",
"api-platform/openapi",
"api-platform/graphql",
"api-platform/http-cache",
"api-platform/documentation",
"api-platform/parameter-validator",
"api-platform/ramsey-uuid",
"api-platform/serializer",
"api-platform/state",
"api-platform/symfony",
"api-platform/validator"
]
},
"autoload": {
"psr-4": {
"ApiPlatform\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kévin Dunglas",
"email": "kevin@dunglas.fr",
"homepage": "https://dunglas.fr"
}
],
"description": "Build a fully-featured hypermedia or GraphQL API in minutes!",
"homepage": "https://api-platform.com",
"keywords": [
"Hydra",
"JSON-LD",
"api",
"graphql",
"hal",
"jsonapi",
"openapi",
"rest",
"swagger"
],
"support": {
"issues": "https://github.com/api-platform/core/issues",
"source": "https://github.com/api-platform/core/tree/v3.3.9"
},
"time": "2024-07-15T14:54:13+00:00"
},
{ {
"name": "composer/semver", "name": "composer/semver",
"version": "3.4.2", "version": "3.4.2",
@ -1541,6 +1729,68 @@
], ],
"time": "2024-06-28T09:40:51+00:00" "time": "2024-06-28T09:40:51+00:00"
}, },
{
"name": "nelmio/cors-bundle",
"version": "2.5.0",
"source": {
"type": "git",
"url": "https://github.com/nelmio/NelmioCorsBundle.git",
"reference": "3a526fe025cd20e04a6a11370cf5ab28dbb5a544"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nelmio/NelmioCorsBundle/zipball/3a526fe025cd20e04a6a11370cf5ab28dbb5a544",
"reference": "3a526fe025cd20e04a6a11370cf5ab28dbb5a544",
"shasum": ""
},
"require": {
"psr/log": "^1.0 || ^2.0 || ^3.0",
"symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0"
},
"require-dev": {
"mockery/mockery": "^1.3.6",
"symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"Nelmio\\CorsBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nelmio",
"homepage": "http://nelm.io"
},
{
"name": "Symfony Community",
"homepage": "https://github.com/nelmio/NelmioCorsBundle/contributors"
}
],
"description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Symfony application",
"keywords": [
"api",
"cors",
"crossdomain"
],
"support": {
"issues": "https://github.com/nelmio/NelmioCorsBundle/issues",
"source": "https://github.com/nelmio/NelmioCorsBundle/tree/2.5.0"
},
"time": "2024-06-24T21:25:28+00:00"
},
{ {
"name": "phpdocumentor/reflection-common", "name": "phpdocumentor/reflection-common",
"version": "2.2.0", "version": "2.2.0",
@ -8107,6 +8357,62 @@
"source": "https://github.com/webmozarts/assert/tree/1.11.0" "source": "https://github.com/webmozarts/assert/tree/1.11.0"
}, },
"time": "2022-06-03T18:03:27+00:00" "time": "2022-06-03T18:03:27+00:00"
},
{
"name": "willdurand/negotiation",
"version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/willdurand/Negotiation.git",
"reference": "68e9ea0553ef6e2ee8db5c1d98829f111e623ec2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/willdurand/Negotiation/zipball/68e9ea0553ef6e2ee8db5c1d98829f111e623ec2",
"reference": "68e9ea0553ef6e2ee8db5c1d98829f111e623ec2",
"shasum": ""
},
"require": {
"php": ">=7.1.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"Negotiation\\": "src/Negotiation"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "William Durand",
"email": "will+git@drnd.me"
}
],
"description": "Content Negotiation tools for PHP provided as a standalone library.",
"homepage": "http://williamdurand.fr/Negotiation/",
"keywords": [
"accept",
"content",
"format",
"header",
"negotiation"
],
"support": {
"issues": "https://github.com/willdurand/Negotiation/issues",
"source": "https://github.com/willdurand/Negotiation/tree/3.1.0"
},
"time": "2022-01-30T20:08:53+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [

View File

@ -13,4 +13,6 @@ return [
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
]; ];

View File

@ -0,0 +1,20 @@
api_platform:
title: Domain Watchdog API
version: 1.0.0
formats:
jsonld: ['application/ld+json']
json: ['application/json']
docs_formats:
jsonld: ['application/ld+json']
jsonopenapi: ['application/vnd.openapi+json']
html: ['text/html']
defaults:
stateless: true
cache_headers:
vary: ['Content-Type', 'Authorization', 'Origin']
extra_properties:
standard_put: true
rfc_7807_compliant_errors: true
keep_legacy_inflector: false
use_symfony_listeners: true
show_webby: false

View File

@ -0,0 +1,10 @@
nelmio_cors:
defaults:
origin_regex: true
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
expose_headers: ['Link']
max_age: 3600
paths:
'^/': null

View File

@ -0,0 +1,4 @@
api_platform:
resource: .
type: api_platform
prefix: /api

0
src/ApiResource/.gitignore vendored Normal file
View File

View File

@ -2,35 +2,60 @@
namespace App\Entity; namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use App\Repository\DomainRepository; use App\Repository\DomainRepository;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Attribute\Groups;
#[ORM\Entity(repositoryClass: DomainRepository::class)] #[ORM\Entity(repositoryClass: DomainRepository::class)]
#[UniqueEntity('handle')]
#[ApiResource(
operations: [
new Get(
uriTemplate: '/domains/{ldhName}',
normalizationContext: ['groups' => [
'domain:item',
'event:list',
'entity:list',
'domain-entity:entity',
'nameserver-entity:nameserver',
'nameserver:item',
]]
)
]
)]
class Domain class Domain
{ {
#[ORM\Id] #[ORM\Id]
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]
#[Groups(['domain:item'])]
private ?string $ldhName = null; private ?string $ldhName = null;
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]
#[Groups(['domain:item'])]
private ?string $handle = null; private ?string $handle = null;
/** /**
* @var Collection<int, DomainEvent> * @var Collection<int, DomainEvent>
*/ */
#[ORM\OneToMany(targetEntity: DomainEvent::class, mappedBy: 'domain', cascade: ['persist'], orphanRemoval: true)] #[ORM\OneToMany(targetEntity: DomainEvent::class, mappedBy: 'domain', cascade: ['persist'], orphanRemoval: true)]
#[Groups(['domain:item'])]
private Collection $events; private Collection $events;
/** /**
* @var Collection<int, DomainEntity> * @var Collection<int, DomainEntity>
*/ */
#[ORM\OneToMany(targetEntity: DomainEntity::class, mappedBy: 'domain', cascade: ['persist'], orphanRemoval: true)] #[ORM\OneToMany(targetEntity: DomainEntity::class, mappedBy: 'domain', cascade: ['persist'], orphanRemoval: true)]
#[Groups(['domain:item'])]
private Collection $domainEntities; private Collection $domainEntities;
#[ORM\Column(type: Types::SIMPLE_ARRAY)] #[ORM\Column(type: Types::SIMPLE_ARRAY)]
#[Groups(['domain:item'])]
private array $status = []; private array $status = [];
/** /**
@ -47,6 +72,7 @@ class Domain
joinColumns: [new ORM\JoinColumn(name: 'domain_ldh_name', referencedColumnName: 'ldh_name')], joinColumns: [new ORM\JoinColumn(name: 'domain_ldh_name', referencedColumnName: 'ldh_name')],
inverseJoinColumns: [new ORM\JoinColumn(name: 'nameserver_ldh_name', referencedColumnName: 'ldh_name')] inverseJoinColumns: [new ORM\JoinColumn(name: 'nameserver_ldh_name', referencedColumnName: 'ldh_name')]
)] )]
#[Groups(['domain:item'])]
private Collection $nameservers; private Collection $nameservers;
public function __construct() public function __construct()

View File

@ -6,6 +6,7 @@ use App\Config\DomainRole;
use App\Repository\DomainEntityRepository; use App\Repository\DomainEntityRepository;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ORM\Entity(repositoryClass: DomainEntityRepository::class)] #[ORM\Entity(repositoryClass: DomainEntityRepository::class)]
class DomainEntity class DomainEntity
@ -13,14 +14,17 @@ class DomainEntity
#[ORM\Id] #[ORM\Id]
#[ORM\ManyToOne(targetEntity: Domain::class, cascade: ['persist'], inversedBy: 'domainEntities')] #[ORM\ManyToOne(targetEntity: Domain::class, cascade: ['persist'], inversedBy: 'domainEntities')]
#[ORM\JoinColumn(referencedColumnName: 'ldh_name', nullable: false)] #[ORM\JoinColumn(referencedColumnName: 'ldh_name', nullable: false)]
#[Groups('domain-entity:domain')]
private ?Domain $domain = null; private ?Domain $domain = null;
#[ORM\Id] #[ORM\Id]
#[ORM\ManyToOne(targetEntity: Entity::class, cascade: ['persist'], inversedBy: 'domainEntities')] #[ORM\ManyToOne(targetEntity: Entity::class, cascade: ['persist'], inversedBy: 'domainEntities')]
#[ORM\JoinColumn(referencedColumnName: 'handle', nullable: false)] #[ORM\JoinColumn(referencedColumnName: 'handle', nullable: false)]
#[Groups(['domain-entity:entity'])]
private ?Entity $entity = null; private ?Entity $entity = null;
#[ORM\Column(type: Types::SIMPLE_ARRAY, enumType: DomainRole::class)] #[ORM\Column(type: Types::SIMPLE_ARRAY, enumType: DomainRole::class)]
#[Groups(['domain-entity:entity', 'domain-entity:domain'])]
private array $roles = []; private array $roles = [];

View File

@ -2,10 +2,22 @@
namespace App\Entity; namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use App\Repository\DomainEventRepository; use App\Repository\DomainEventRepository;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: DomainEventRepository::class)] #[ORM\Entity(repositoryClass: DomainEventRepository::class)]
#[ApiResource(
operations: [
new Get(
uriTemplate: '/events/domain/{id}',
shortName: 'Domain Event',
class: DomainEvent::class,
normalizationContext: ['groups' => ['event:list']]
)
]
)]
class DomainEvent extends Event class DomainEvent extends Event
{ {
#[ORM\ManyToOne(targetEntity: Domain::class, cascade: ['persist'], inversedBy: 'events')] #[ORM\ManyToOne(targetEntity: Domain::class, cascade: ['persist'], inversedBy: 'events')]

View File

@ -2,39 +2,67 @@
namespace App\Entity; namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use App\Repository\EntityRepository; use App\Repository\EntityRepository;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ORM\Entity(repositoryClass: EntityRepository::class)] #[ORM\Entity(repositoryClass: EntityRepository::class)]
#[ApiResource(
operations: [
new GetCollection(
uriTemplate: '/entities',
normalizationContext: ['groups' => ['entity:list', 'event:list']]
),
new Get(
uriTemplate: '/entities/{handle}',
normalizationContext: [
'groups' => [
'event:list',
'entity:item',
'domain-entity:domain',
'nameserver-entity:nameserver'
]
]
)
]
)]
class Entity class Entity
{ {
#[ORM\Id] #[ORM\Id]
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]
#[Groups(['entity:list', 'entity:item'])]
private ?string $handle = null; private ?string $handle = null;
/** /**
* @var Collection<int, DomainEntity> * @var Collection<int, DomainEntity>
*/ */
#[ORM\OneToMany(targetEntity: DomainEntity::class, mappedBy: 'entity', orphanRemoval: true)] #[ORM\OneToMany(targetEntity: DomainEntity::class, mappedBy: 'entity', orphanRemoval: true)]
#[Groups(['entity:item'])]
private Collection $domainEntities; private Collection $domainEntities;
/** /**
* @var Collection<int, NameserverEntity> * @var Collection<int, NameserverEntity>
*/ */
#[ORM\OneToMany(targetEntity: NameserverEntity::class, mappedBy: 'entity')] #[ORM\OneToMany(targetEntity: NameserverEntity::class, mappedBy: 'entity')]
#[Groups(['entity:item'])]
private Collection $nameserverEntities; private Collection $nameserverEntities;
/** /**
* @var Collection<int, EntityEvent> * @var Collection<int, EntityEvent>
*/ */
#[ORM\OneToMany(targetEntity: EntityEvent::class, mappedBy: 'entity', cascade: ['persist'], orphanRemoval: true)] #[ORM\OneToMany(targetEntity: EntityEvent::class, mappedBy: 'entity', cascade: ['persist'], orphanRemoval: true)]
#[Groups(['entity:list', 'entity:item'])]
private Collection $events; private Collection $events;
#[ORM\Column] #[ORM\Column]
#[Groups(['entity:item'])]
private array $jCard = []; private array $jCard = [];
public function __construct() public function __construct()

View File

@ -2,10 +2,24 @@
namespace App\Entity; namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use App\Repository\EntityEventRepository; use App\Repository\EntityEventRepository;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: EntityEventRepository::class)] #[ORM\Entity(repositoryClass: EntityEventRepository::class)]
#[ApiResource(
operations: [
new Get(
uriTemplate: '/events/entity/{id}',
shortName: 'Entity Event',
class: EntityEvent::class,
normalizationContext: [
'groups' => ['event:list']
]
)
]
)]
class EntityEvent extends Event class EntityEvent extends Event
{ {
@ -14,7 +28,6 @@ class EntityEvent extends Event
private ?Entity $entity = null; private ?Entity $entity = null;
public function getEntity(): ?Entity public function getEntity(): ?Entity
{ {
return $this->entity; return $this->entity;

View File

@ -2,9 +2,12 @@
namespace App\Entity; namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use App\Config\EventAction; use App\Config\EventAction;
use DateTimeImmutable; use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ORM\MappedSuperclass] #[ORM\MappedSuperclass]
class Event class Event
@ -15,9 +18,11 @@ class Event
private ?int $id = null; private ?int $id = null;
#[ORM\Column(enumType: EventAction::class)] #[ORM\Column(enumType: EventAction::class)]
#[Groups(['event:list'])]
private ?EventAction $action = null; private ?EventAction $action = null;
#[ORM\Column(type: 'datetime_immutable')] #[ORM\Column(type: 'datetime_immutable')]
#[Groups(['event:list'])]
private ?DateTimeImmutable $date = null; private ?DateTimeImmutable $date = null;

View File

@ -2,23 +2,42 @@
namespace App\Entity; namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use App\Repository\NameserverRepository; use App\Repository\NameserverRepository;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ORM\Entity(repositoryClass: NameserverRepository::class)] #[ORM\Entity(repositoryClass: NameserverRepository::class)]
#[ApiResource(
operations: [
new Get(
uriTemplate: '/nameservers/{ldhName}',
normalizationContext: [
'groups' => [
'nameserver:item',
'entity:list',
'nameserver-entity:entity'
]
]
)
]
)]
class Nameserver class Nameserver
{ {
#[ORM\Id] #[ORM\Id]
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]
#[Groups(['nameserver:item'])]
private ?string $ldhName = null; private ?string $ldhName = null;
/** /**
* @var Collection<int, NameserverEntity> * @var Collection<int, NameserverEntity>
*/ */
#[ORM\OneToMany(targetEntity: NameserverEntity::class, mappedBy: 'nameserver', cascade: ['persist'], orphanRemoval: true)] #[ORM\OneToMany(targetEntity: NameserverEntity::class, mappedBy: 'nameserver', cascade: ['persist'], orphanRemoval: true)]
#[Groups(['nameserver:item'])]
private Collection $nameserverEntities; private Collection $nameserverEntities;
/** /**

View File

@ -6,6 +6,7 @@ use App\Config\DomainRole;
use App\Repository\NameserverEntityRepository; use App\Repository\NameserverEntityRepository;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ORM\Entity(repositoryClass: NameserverEntityRepository::class)] #[ORM\Entity(repositoryClass: NameserverEntityRepository::class)]
class NameserverEntity class NameserverEntity
@ -13,18 +14,22 @@ class NameserverEntity
#[ORM\Id] #[ORM\Id]
#[ORM\ManyToOne(targetEntity: Nameserver::class, cascade: ['persist'], inversedBy: 'nameserverEntities')] #[ORM\ManyToOne(targetEntity: Nameserver::class, cascade: ['persist'], inversedBy: 'nameserverEntities')]
#[ORM\JoinColumn(referencedColumnName: 'ldh_name', nullable: false)] #[ORM\JoinColumn(referencedColumnName: 'ldh_name', nullable: false)]
#[Groups(['nameserver-entity:nameserver'])]
private ?Nameserver $nameserver = null; private ?Nameserver $nameserver = null;
#[ORM\Id] #[ORM\Id]
#[ORM\ManyToOne(targetEntity: Entity::class, cascade: ['persist'], inversedBy: 'nameserverEntities')] #[ORM\ManyToOne(targetEntity: Entity::class, cascade: ['persist'], inversedBy: 'nameserverEntities')]
#[ORM\JoinColumn(referencedColumnName: 'handle', nullable: false)] #[ORM\JoinColumn(referencedColumnName: 'handle', nullable: false)]
#[Groups(['nameserver-entity:entity'])]
private ?Entity $entity = null; private ?Entity $entity = null;
#[ORM\Column(type: Types::SIMPLE_ARRAY, enumType: DomainRole::class)] #[ORM\Column(type: Types::SIMPLE_ARRAY, enumType: DomainRole::class)]
#[Groups(['nameserver-entity:entity', 'nameserver-entity:nameserver'])]
private array $roles = []; private array $roles = [];
#[ORM\Column(type: Types::SIMPLE_ARRAY)] #[ORM\Column(type: Types::SIMPLE_ARRAY)]
#[Groups(['nameserver-entity:entity', 'nameserver-entity:nameserver'])]
private array $status = []; private array $status = [];
public function getNameserver(): ?Nameserver public function getNameserver(): ?Nameserver

View File

@ -1,4 +1,18 @@
{ {
"api-platform/core": {
"version": "3.3",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "3.3",
"ref": "74b45ac570c57eb1fbe56c984091a9ff87e18bab"
},
"files": [
"config/packages/api_platform.yaml",
"config/routes/api_platform.yaml",
"src/ApiResource/.gitignore"
]
},
"doctrine/doctrine-bundle": { "doctrine/doctrine-bundle": {
"version": "2.12", "version": "2.12",
"recipe": { "recipe": {
@ -26,6 +40,18 @@
"migrations/.gitignore" "migrations/.gitignore"
] ]
}, },
"nelmio/cors-bundle": {
"version": "2.5",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "1.5",
"ref": "6bea22e6c564fba3a1391615cada1437d0bde39c"
},
"files": [
"config/packages/nelmio_cors.yaml"
]
},
"phpunit/phpunit": { "phpunit/phpunit": {
"version": "9.6", "version": "9.6",
"recipe": { "recipe": {

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title> <title>{% block title %}Welcome!{% endblock %}</title>