GdprRequest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <?php
  2. namespace Webkul\BagistoApi\Models;
  3. use ApiPlatform\Metadata\ApiProperty;
  4. use ApiPlatform\Metadata\ApiResource;
  5. use ApiPlatform\Metadata\Delete;
  6. use ApiPlatform\Metadata\Get;
  7. use ApiPlatform\Metadata\GetCollection;
  8. use ApiPlatform\Metadata\GraphQl\Mutation;
  9. use ApiPlatform\Metadata\GraphQl\Query;
  10. use ApiPlatform\Metadata\GraphQl\QueryCollection;
  11. use ApiPlatform\Metadata\Post;
  12. use Webkul\BagistoApi\Dto\CreateGdprRequestInput;
  13. use Webkul\BagistoApi\Dto\DeleteGdprRequestInput;
  14. use Webkul\BagistoApi\Dto\RevokeGdprRequestInput;
  15. use Webkul\BagistoApi\Resolver\GdprRequestQueryResolver;
  16. use Webkul\BagistoApi\State\GdprRequestItemProvider;
  17. use Webkul\BagistoApi\State\GdprRequestProcessor;
  18. use Webkul\BagistoApi\State\GdprRequestProvider;
  19. use ApiPlatform\OpenApi\Model\Operation;
  20. #[ApiResource(
  21. shortName: 'GdprRequest',
  22. routePrefix: '/api/shop',
  23. normalizationContext: ['skip_null_values' => false],
  24. operations: [
  25. new Get(
  26. uriTemplate: '/gdpr-requests/{id}',
  27. provider: GdprRequestItemProvider::class,
  28. openapi: new Operation(
  29. tags: ['GDPR Requests'],
  30. summary: 'Get one of the customer\'s own GDPR data requests',
  31. description: 'Returns a GDPR data request owned by the authenticated customer. Returns 404 if it is not theirs. Requires GDPR to be enabled in admin config.',
  32. responses: [
  33. '200' => new \ApiPlatform\OpenApi\Model\Response(
  34. description: 'The GDPR data request.',
  35. content: new \ArrayObject([
  36. 'application/json' => [
  37. 'example' => [
  38. 'id' => 35,
  39. 'email' => 'jane@example.com',
  40. 'status' => 'pending',
  41. 'type' => 'delete',
  42. 'message' => 'Please delete my personal data.',
  43. 'revokedAt' => null,
  44. 'createdAt' => '2026-07-02T12:01:36+05:30',
  45. 'updatedAt' => '2026-07-02T12:01:36+05:30',
  46. 'successMessage' => null,
  47. 'customer' => '/api/shop/customers/1534',
  48. ],
  49. ],
  50. ]),
  51. ),
  52. '404' => new \ApiPlatform\OpenApi\Model\Response(description: 'Request not found or not owned by the caller.'),
  53. ],
  54. ),
  55. ),
  56. new GetCollection(
  57. uriTemplate: '/gdpr-requests',
  58. provider: GdprRequestProvider::class,
  59. openapi: new Operation(
  60. tags: ['GDPR Requests'],
  61. summary: 'List the customer\'s own GDPR data requests',
  62. description: 'Returns every GDPR data request raised by the authenticated customer. Requires GDPR to be enabled in admin config.',
  63. responses: [
  64. '200' => new \ApiPlatform\OpenApi\Model\Response(
  65. description: 'List of the customer\'s GDPR data requests.',
  66. content: new \ArrayObject([
  67. 'application/json' => [
  68. 'example' => [
  69. [
  70. 'id' => 35,
  71. 'email' => 'jane@example.com',
  72. 'status' => 'pending',
  73. 'type' => 'delete',
  74. 'message' => 'Please delete my personal data.',
  75. 'revokedAt' => null,
  76. 'createdAt' => '2026-07-02T12:01:36+05:30',
  77. 'updatedAt' => '2026-07-02T12:01:36+05:30',
  78. 'successMessage' => null,
  79. 'customer' => '/api/shop/customers/1534',
  80. ],
  81. ],
  82. ],
  83. ]),
  84. ),
  85. ],
  86. parameters: [
  87. new \ApiPlatform\OpenApi\Model\Parameter(
  88. name: 'sort',
  89. in: 'query',
  90. description: 'Column to sort by: `id` (default) or `created_at`.',
  91. required: false,
  92. schema: ['type' => 'string', 'enum' => ['id', 'created_at', 'id-asc', 'id-desc', 'created_at-asc', 'created_at-desc']],
  93. ),
  94. new \ApiPlatform\OpenApi\Model\Parameter(
  95. name: 'order',
  96. in: 'query',
  97. description: 'Sort direction: `asc` (default) or `desc`.',
  98. required: false,
  99. schema: ['type' => 'string', 'enum' => ['asc', 'desc']],
  100. ),
  101. ],
  102. ),
  103. ),
  104. new Post(
  105. uriTemplate: '/gdpr-requests',
  106. processor: GdprRequestProcessor::class,
  107. openapi: new Operation(
  108. tags: ['GDPR Requests'],
  109. summary: 'Raise a GDPR data request',
  110. description: 'Raise a GDPR data request for the authenticated customer. Type must be `delete` or `update`.',
  111. requestBody: new \ApiPlatform\OpenApi\Model\RequestBody(
  112. description: 'GDPR data request details',
  113. required: true,
  114. content: new \ArrayObject([
  115. 'application/json' => [
  116. 'schema' => [
  117. 'type' => 'object',
  118. 'required' => ['type', 'message'],
  119. 'properties' => [
  120. 'type' => ['type' => 'string', 'enum' => ['delete', 'update'], 'example' => 'delete'],
  121. 'message' => ['type' => 'string', 'example' => 'Please delete all my personal data.'],
  122. ],
  123. ],
  124. 'example' => [
  125. 'type' => 'delete',
  126. 'message' => 'Please delete my personal data.',
  127. ],
  128. ],
  129. ]),
  130. ),
  131. responses: [
  132. '201' => new \ApiPlatform\OpenApi\Model\Response(
  133. description: 'Request raised. Starts in `pending` status.',
  134. content: new \ArrayObject([
  135. 'application/json' => [
  136. 'example' => [
  137. 'id' => 35,
  138. 'email' => 'jane@example.com',
  139. 'status' => 'pending',
  140. 'type' => 'delete',
  141. 'message' => 'Please delete my personal data.',
  142. 'revokedAt' => null,
  143. 'createdAt' => '2026-07-02T12:01:36+05:30',
  144. 'updatedAt' => '2026-07-02T12:01:36+05:30',
  145. 'successMessage' => 'Your GDPR data request has been raised successfully.',
  146. 'customer' => '/api/shop/customers/1534',
  147. ],
  148. ],
  149. ]),
  150. ),
  151. '400' => new \ApiPlatform\OpenApi\Model\Response(description: 'GDPR disabled in admin config, or invalid type/message.'),
  152. ],
  153. ),
  154. ),
  155. new Post(
  156. name: 'revoke_post',
  157. uriTemplate: '/gdpr-requests/{id}/revoke',
  158. status: 200,
  159. processor: GdprRequestProcessor::class,
  160. openapi: new Operation(
  161. tags: ['GDPR Requests'],
  162. summary: 'Revoke a GDPR data request',
  163. description: 'Revoke one of the customer\'s own GDPR data requests. Allowed only while the request is pending or processing. Send an empty JSON body `{}`.',
  164. responses: [
  165. '200' => new \ApiPlatform\OpenApi\Model\Response(
  166. description: 'Request revoked. `status` becomes `revoked` and `revokedAt` is stamped.',
  167. content: new \ArrayObject([
  168. 'application/json' => [
  169. 'example' => [
  170. 'id' => 35,
  171. 'email' => 'jane@example.com',
  172. 'status' => 'revoked',
  173. 'type' => 'delete',
  174. 'message' => 'Please delete my personal data.',
  175. 'revokedAt' => '2026-07-02 12:01:37',
  176. 'createdAt' => '2026-07-02T12:01:36+05:30',
  177. 'updatedAt' => '2026-07-02T12:01:37+05:30',
  178. 'successMessage' => null,
  179. 'customer' => '/api/shop/customers/1534',
  180. ],
  181. ],
  182. ]),
  183. ),
  184. '422' => new \ApiPlatform\OpenApi\Model\Response(description: 'Request is not pending/processing, so it cannot be revoked.'),
  185. ],
  186. ),
  187. ),
  188. new Delete(
  189. uriTemplate: '/gdpr-requests/{id}',
  190. processor: GdprRequestProcessor::class,
  191. openapi: new Operation(
  192. tags: ['GDPR Requests'],
  193. summary: 'Delete a GDPR data request',
  194. description: 'Deletes one of the customer\'s own GDPR data requests. Returns 204 No Content on success.',
  195. responses: [
  196. '204' => new \ApiPlatform\OpenApi\Model\Response(description: 'Request deleted. No content.'),
  197. '404' => new \ApiPlatform\OpenApi\Model\Response(description: 'Request not found or not owned by the caller.'),
  198. ],
  199. ),
  200. ),
  201. ],
  202. graphQlOperations: [
  203. new Query(resolver: GdprRequestQueryResolver::class),
  204. new QueryCollection(
  205. provider: GdprRequestProvider::class,
  206. paginationType: 'cursor',
  207. extraArgs: [
  208. 'sort' => ['type' => 'String'],
  209. 'order' => ['type' => 'String'],
  210. ],
  211. ),
  212. new Mutation(
  213. name: 'create',
  214. input: CreateGdprRequestInput::class,
  215. output: GdprRequest::class,
  216. processor: GdprRequestProcessor::class,
  217. ),
  218. new Mutation(
  219. name: 'revoke',
  220. input: RevokeGdprRequestInput::class,
  221. output: GdprRequest::class,
  222. processor: GdprRequestProcessor::class,
  223. ),
  224. new Mutation(
  225. name: 'delete',
  226. input: DeleteGdprRequestInput::class,
  227. output: GdprRequest::class,
  228. processor: GdprRequestProcessor::class,
  229. ),
  230. ],
  231. )]
  232. class GdprRequest extends \Webkul\GDPR\Models\GDPRDataRequest
  233. {
  234. protected $appends = ['success_message'];
  235. public ?string $responseMessage = null;
  236. #[ApiProperty(identifier: true, writable: false)]
  237. public function getId(): int
  238. {
  239. return $this->id;
  240. }
  241. #[ApiProperty(writable: false, description: 'The customer who owns the request')]
  242. public function customer(): \Illuminate\Database\Eloquent\Relations\BelongsTo
  243. {
  244. return $this->belongsTo(Customer::class, 'customer_id');
  245. }
  246. public function getSuccessMessageAttribute(): ?string
  247. {
  248. return $this->responseMessage;
  249. }
  250. public function setResponseMessage(string $message): self
  251. {
  252. $this->responseMessage = $message;
  253. return $this;
  254. }
  255. }