diff --git a/docs/api/intro.md b/docs/api/intro.md index 2c9c1fa1..44b0db19 100644 --- a/docs/api/intro.md +++ b/docs/api/intro.md @@ -58,6 +58,8 @@ The API supports different formats for the request and response data, which you You should use [JSON-LD](https://json-ld.org/) as format, which is basically JSON with some additional metadata, which allows to describe the data in a more structured way and also allows to link between different entities. You can achieve this by setting `Accept: application/ld+json` header to the API requests. +To get plain JSON without any metadata or links, use the `Accept: application/json` header. + ## OpenAPI schema Part-DB provides a [OpenAPI](https://swagger.io/specification/) (formally Swagger) schema for the API under `/api/docs.json` (so `https://your-part-db.local/api/docs.json`). diff --git a/src/Entity/Attachments/AttachmentType.php b/src/Entity/Attachments/AttachmentType.php index 23c3d322..c6791d90 100644 --- a/src/Entity/Attachments/AttachmentType.php +++ b/src/Entity/Attachments/AttachmentType.php @@ -117,6 +117,7 @@ class AttachmentType extends AbstractStructuralDBElement #[Assert\Valid] #[ORM\OneToMany(targetEntity: AttachmentTypeParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] + #[Groups(['attachment_type:read', 'attachment_type:write'])] protected Collection $parameters; /** diff --git a/src/Entity/Parameters/AbstractParameter.php b/src/Entity/Parameters/AbstractParameter.php index a3cef469..7e90a546 100644 --- a/src/Entity/Parameters/AbstractParameter.php +++ b/src/Entity/Parameters/AbstractParameter.php @@ -41,6 +41,12 @@ declare(strict_types=1); namespace App\Entity\Parameters; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; use App\Entity\Attachments\AttachmentTypeAttachment; use App\Repository\ParameterRepository; use Doctrine\DBAL\Types\Types; @@ -49,7 +55,9 @@ use App\Entity\Base\AbstractNamedDBElement; use Doctrine\ORM\Mapping as ORM; use InvalidArgumentException; use LogicException; +use PHPUnit\Framework\Attributes\Group; use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Annotation\SerializedName; use Symfony\Component\Validator\Constraints as Assert; use function sprintf; @@ -65,6 +73,17 @@ use function sprintf; #[ORM\Index(name: 'parameter_name_idx', columns: ['name'])] #[ORM\Index(name: 'parameter_group_idx', columns: ['param_group'])] #[ORM\Index(name: 'parameter_type_element_idx', columns: ['type', 'element_id'])] +#[ApiResource( + shortName: 'Parameter', + operations: [ + new Get(security: 'is_granted("read", object)'), + new Post(securityPostDenormalize: 'is_granted("create", object)'), + new Patch(security: 'is_granted("edit", object)'), + new Delete(security: 'is_granted("delete", object)'), + ], + normalizationContext: ['groups' => ['parameter:read', 'parameter:read:standalone', 'api:basic:read'], 'openapi_definition_name' => 'Read'], + denormalizationContext: ['groups' => ['parameter:write', 'api:basic:write'], 'openapi_definition_name' => 'Write'], +)] abstract class AbstractParameter extends AbstractNamedDBElement { /** @@ -76,7 +95,7 @@ abstract class AbstractParameter extends AbstractNamedDBElement * @var string The mathematical symbol for this specification. Can be rendered pretty later. Should be short */ #[Assert\Length(max: 20)] - #[Groups(['full'])] + #[Groups(['full', 'parameter:read', 'parameter:write'])] #[ORM\Column(type: Types::STRING)] protected string $symbol = ''; @@ -86,7 +105,7 @@ abstract class AbstractParameter extends AbstractNamedDBElement #[Assert\Type(['float', null])] #[Assert\LessThanOrEqual(propertyPath: 'value_typical', message: 'parameters.validator.min_lesser_typical')] #[Assert\LessThan(propertyPath: 'value_max', message: 'parameters.validator.min_lesser_max')] - #[Groups(['full'])] + #[Groups(['full', 'parameter:read', 'parameter_write'])] #[ORM\Column(type: Types::FLOAT, nullable: true)] protected ?float $value_min = null; @@ -94,7 +113,7 @@ abstract class AbstractParameter extends AbstractNamedDBElement * @var float|null the typical value of this property */ #[Assert\Type([null, 'float'])] - #[Groups(['full'])] + #[Groups(['full', 'parameter:read', 'parameter:write'])] #[ORM\Column(type: Types::FLOAT, nullable: true)] protected ?float $value_typical = null; @@ -110,21 +129,21 @@ abstract class AbstractParameter extends AbstractNamedDBElement /** * @var string The unit in which the value values are given (e.g. V) */ - #[Groups(['full'])] + #[Groups(['full', 'parameter:read', 'parameter:write'])] #[ORM\Column(type: Types::STRING)] protected string $unit = ''; /** * @var string a text value for the given property */ - #[Groups(['full'])] + #[Groups(['full', 'parameter:read', 'parameter:write'])] #[ORM\Column(type: Types::STRING)] protected string $value_text = ''; /** * @var string the group this parameter belongs to */ - #[Groups(['full'])] + #[Groups(['full', 'parameter:read', 'parameter:write'])] #[ORM\Column(type: Types::STRING, name: 'param_group')] protected string $group = ''; @@ -133,6 +152,7 @@ abstract class AbstractParameter extends AbstractNamedDBElement * * @var AbstractDBElement|null the element to which this parameter belongs to */ + #[Groups(['parameter:read:standalone', 'parameter:write'])] protected ?AbstractDBElement $element = null; public function __construct() @@ -162,6 +182,8 @@ abstract class AbstractParameter extends AbstractNamedDBElement * Return a formatted string version of the values of the string. * Based on the set values it can return something like this: 34 V (12 V ... 50 V) [Text]. */ + #[Groups('parameter:read', 'full')] + #[SerializedName('formatted')] public function getFormattedValue(): string { //If we just only have text value, return early diff --git a/src/Entity/Parts/Category.php b/src/Entity/Parts/Category.php index 11731ab6..b32cbbf4 100644 --- a/src/Entity/Parts/Category.php +++ b/src/Entity/Parts/Category.php @@ -165,7 +165,7 @@ class Category extends AbstractPartsContainingDBElement /** @var Collection */ #[Assert\Valid] - #[Groups(['full', 'category:read'])] + #[Groups(['full', 'category:read', 'category:write'])] #[ORM\OneToMany(targetEntity: CategoryParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; diff --git a/src/Entity/Parts/Footprint.php b/src/Entity/Parts/Footprint.php index edeb31cc..8dde5931 100644 --- a/src/Entity/Parts/Footprint.php +++ b/src/Entity/Parts/Footprint.php @@ -119,7 +119,7 @@ class Footprint extends AbstractPartsContainingDBElement #[Assert\Valid] #[ORM\OneToMany(targetEntity: FootprintParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] - #[Groups(['footprint:read'])] + #[Groups(['footprint:read', 'footprint:write'])] protected Collection $parameters; /**************************************** diff --git a/src/Entity/Parts/MeasurementUnit.php b/src/Entity/Parts/MeasurementUnit.php index 2b7130c9..7d9e76a4 100644 --- a/src/Entity/Parts/MeasurementUnit.php +++ b/src/Entity/Parts/MeasurementUnit.php @@ -141,7 +141,7 @@ class MeasurementUnit extends AbstractPartsContainingDBElement #[Assert\Valid] #[ORM\OneToMany(targetEntity: MeasurementUnitParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] - #[Groups(['measurement_unit:read'])] + #[Groups(['measurement_unit:read', 'measurement_unit:write'])] protected Collection $parameters; /** diff --git a/src/Entity/Parts/Part.php b/src/Entity/Parts/Part.php index 1f7ace26..56e6638b 100644 --- a/src/Entity/Parts/Part.php +++ b/src/Entity/Parts/Part.php @@ -73,7 +73,9 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; #[ApiResource( operations: [ new Get(normalizationContext: ['groups' => ['part:read', 'provider_reference:read', 'api:basic:read', 'part_lot:read', - 'orderdetail:read', 'pricedetail:read', 'attachment:read']], security: 'is_granted("read", object)'), + 'orderdetail:read', 'pricedetail:read', 'parameter:read', 'attachment:read'], + 'openapi_definition_name' => 'Read', + ], security: 'is_granted("read", object)'), new GetCollection(security: 'is_granted("@parts.read")'), new Post(securityPostDenormalize: 'is_granted("create", object)'), new Patch(security: 'is_granted("edit", object)'), @@ -97,7 +99,7 @@ class Part extends AttachmentContainingDBElement /** @var Collection */ #[Assert\Valid] - #[Groups(['full'])] + #[Groups(['full', 'part:read', 'part:write'])] #[ORM\OneToMany(targetEntity: PartParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; diff --git a/src/Entity/Parts/StorageLocation.php b/src/Entity/Parts/StorageLocation.php index c21d3f28..4a11427c 100644 --- a/src/Entity/Parts/StorageLocation.php +++ b/src/Entity/Parts/StorageLocation.php @@ -105,6 +105,7 @@ class StorageLocation extends AbstractPartsContainingDBElement #[Assert\Valid] #[ORM\OneToMany(targetEntity: StorageLocationParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] + #[Groups(['location:read', 'location:write'])] protected Collection $parameters; /**