Repository navigation
Conversation
|
Hello @boo-code! This is your first pull request on ps_apiresources repository of the PrestaShop project. Thank you, and welcome to this Open Source community! |
Expose two Attachment CQRS read queries that are not covered by the CRUD Attachment resource (PR PrestaShop#295): - GET /attachments/search?phrase= -> SearchAttachment (collection) - GET /attachments/{attachmentId}/file -> GetAttachment (path + original name) Both operations require the attachment_read scope. Search results expose localized name and description fields as locale-keyed maps via #[LocalizedValue]. An empty phrase returns 422 and a search with no match returns 404, mirroring the core SearchAttachment handler behaviour. Kept in dedicated resource classes (FoundAttachment, AttachmentFile) so it does not collide with the CRUD Attachment resource proposed in PR PrestaShop#295.
Expose two Attachment CQRS read queries that are not covered by the CRUD Attachment resource (PR PrestaShop#295): - GET /attachments/search?phrase= -> SearchAttachment (collection) - GET /attachments/{attachmentId}/files -> GetAttachment (path + original name) Both operations require the attachment_read scope. Search results expose the localized name and description fields as locale-keyed maps via #[LocalizedValue]. An empty phrase returns 422 and a search with no match returns 404, mirroring the core SearchAttachment handler behaviour. Kept in dedicated resource classes (FoundAttachment, AttachmentFile) so it does not collide with the CRUD Attachment resource proposed in PR PrestaShop#295. Contributes to PrestaShop/PrestaShop#41946
|
hey @boo-code 👋 nice work on this. one thought while going through the Attachment domain: this PR is currently blocked on core PrestaShop/PrestaShop#41889 because
for reference i added the search + file read endpoints in #311 ( |
|
small correction to my previous comment 🙇 — switching to |
Expose the Attachment CQRS read queries that are not covered by the CRUD Attachment resource (PR PrestaShop#295): - GET /attachments/search?phrase= -> SearchAttachment (collection) - GET /attachments/{attachmentId}/files -> GetAttachment (path + original name) - GET /attachments/{attachmentId}/information -> GetAttachmentInformation (localized names & descriptions, file name, mime type, file size) All operations require the attachment_read scope. Localized fields are exposed as locale-keyed maps via #[LocalizedValue]. For search, an empty phrase returns 422 and no match returns 404, mirroring the core SearchAttachment handler. Kept in dedicated resource classes (FoundAttachment, AttachmentFile, AttachmentInformation) so it does not collide with the CRUD Attachment resource proposed in PR PrestaShop#295, and it requires no core change. Contributes to PrestaShop/PrestaShop#41946
|
update: #311 now also exposes |
|
Thanks @mattgoud, and no worries about the back-and-forth. Agreed on the conclusion: keeping And good that #311 covers |
|
The six integration jobs were failing on all three core refs with:
09d3375 adds a reflection capability probe instead: the two POST paths ( So these jobs stop failing now, and the assertions re-activate on their own once the core change is available, with no further push here. The remaining |
09d3375 to
f4639b2
Compare
| $constructor = (new \ReflectionClass(GetAttachmentForEditing::class))->getConstructor(); | ||
| $parameters = null !== $constructor ? $constructor->getParameters() : []; | ||
|
|
||
| if ([] === $parameters || 'attachmentId' !== $parameters[0]->getName()) { |
There was a problem hiding this comment.
Since PrestaShop/PrestaShop#41889 and #42124 are still open, the GET, POST and PATCH answer 500 on every core of the CI matrix, and this probe turns that into skips: only the empty-list bulk case and the 401 checks run, so the green CI does not exercise any endpoint. Could these three operations declare minVersion on the first core release that ships the fix, with markTestSkippedByMinVersion() in the tests (as in CountryEndpointTest), instead of the reflection check?
| CQRSQueryMapping: self::QUERY_MAPPING, | ||
| CQRSCommandMapping: self::CREATE_COMMAND_MAPPING, | ||
| ), | ||
| new CQRSPartialUpdate( |
There was a problem hiding this comment.
A multipart PATCH reaches the command empty in a real request, since PHP only parses multipart bodies for POST and Symfony re-parses PATCH bodies only when urlencoded; the test passes because the test client injects the parameters. VirtualProductFile and ProductImage use a CQRSUpdate with method: CQRSUpdate::METHOD_POST and status: 200 for this reason, could you do the same? Also, EditAttachmentHandler writes names and descriptions unconditionally (no names ends in a TypeError from getLocalizedNames(), no descriptions clears them), so both look required on that operation until the core handler only applies the sent fields.
| #[LocalizedValue] | ||
| public array $descriptions; | ||
|
|
||
| public ?File $file; |
There was a problem hiding this comment.
A POST without file passes validation, then AddAttachmentHandler throws EmptyFileException, which is not mapped, so it answers 500. Could you require it in the Create group and keep it out of the read schema, like VirtualProductFile::$file?
| public ?File $file; | |
| #[ApiProperty(readable: false, writable: false)] | |
| #[Assert\NotNull(groups: ['Create'])] | |
| public ?File $file = null; |
| #[ApiProperty(openapiContext: ['type' => 'array', 'items' => ['type' => 'integer'], 'example' => [1, 3]])] | ||
| #[Assert\NotBlank] | ||
| #[Assert\Count(min: 1)] | ||
| public array $attachmentIds = []; |
There was a problem hiding this comment.
BulkDeleteAttachmentsHandler collects each failure and throws BulkDeleteAttachmentsException at the end, which is not mapped, so an unknown id answers 500 (and the AttachmentNotFoundException entry never applies); [0] also ends in a 500 through the AttachmentConstraintException of AttachmentId. Could you add #[Assert\All([new Assert\Type('integer'), new Assert\Positive()])] and allowEmptyBody: false as in BulkCountries, map BulkDeleteAttachmentsException (422 seems the closest fit) and test both cases?
| 'attachment_read', | ||
| ], | ||
| ApiResourceMapping: self::MAPPING, | ||
| gridDataFactory: 'prestashop.core.grid.data_factory.attachment_decorator', |
There was a problem hiding this comment.
The _decorator factory turns file_size into a human-readable size and products into a translated "N product(s)" label, which an API client cannot use, unlike the int fileSize of /attachments/{attachmentId}/information. Could you use prestashop.core.grid.data_factory.attachment and type both as int?
Expose CRUD for attachments: GET/POST/PATCH/DELETE /attachments. The create and update operations accept a multipart file upload alongside the localized name and description. Contributes to #39630.
Complete the attachment Admin API resource with the two operations that were missing alongside the CRUD endpoints: a paginated list sourced from the attachment grid, and a bulk-delete endpoint. These port the AttachmentList and BulkAttachments resources from PrestaShop#105, adapted to the current conventions (strict types, camelCase fileSize with ApiResourceMapping, CQRSDelete bulk operation, Count(min:1) validation). The integration test is extended to cover the list (field and filter mapping) and bulk-delete (including the empty-payload validation error). Co-authored-by: Codencode <2463965+Codencode@users.noreply.github.com>
…ultipart POST, validate like the back office
f4639b2 to
7ba30d4
Compare
|
All done, with one deviation:
Not covered: replacing the file through the update. With PrestaShop/PrestaShop#42124 applied on a 9.2.1 core: 16/16, 137 assertions. The new tests on the previous resource: 6 failures. |
|
PrestaShop/PrestaShop#43369 (9.2.1) reads the item type of an array from its
On older cores the arrays are documented without item type, the behaviour is the same. Keep the |
POST /attachments,GET /attachments/{attachmentId},POST /attachments/{attachmentId}(update),DELETE /attachments/{attachmentId},GET /attachmentsandDELETE /attachments/bulk-delete. The creation and the update are multipart requests: thefilepart is required to create, optional to update (the current file is kept), and the localizednamesanddescriptionsare required on both sinceEditAttachmentHandlerwrites them whatever was sent. The update is a POST because PHP only parses the multipart body of a POST. The get, create and update operations declareminVersion9.2.1:GetAttachmentForEditingonly accepts theattachmentIdthe API builds it from with PrestaShop/PrestaShop#42124, older cores answer 500. Until it merges, the 9.2.x and develop legs of the CI are red on those operations. Covered byAttachmentEndpointTest: 16 tests / 137 assertions with #42124 applied on a 9.2.1 core.AttachmentEndpointTeston a core with PrestaShop/PrestaShop#42124. Or: POST a multipart request to/attachmentswithfile,names[<locale>],descriptions[<locale>]; GET and DELETE/attachments/{attachmentId}; POST a multipart request to/attachments/{attachmentId}withnames[<locale>],descriptions[<locale>]and optionallyfile.